HRNet
简介
论文原文: 论文原文)
HRNet是由中国科学技术大学和亚洲微软研究院在2019年共同发表的, 这篇文章中的HRNet(High-Resolution Net)是针对2D人体姿态估计任务提出的, 并且该网络主要针对单一人体姿态估计。人体姿态估计主要应用在人体行为识别、人机交互、动画制作等。
主要由两种深度学习方法处理Human Pose Estimation任务。
1、基于regression的方式, 即直接预测每个关键点的位置坐标
2、基于heatmap的方式, 即针对每个关键点预测一张热度图(预测出现在每个位置上的分数)
HRNet
下图是根据源码绘制的HRNet-w32的模型结构简图, 文章中还提到了HENet-w48版本, 二者的区别在于每个模块所采用的通道个数不同, 网路的整体结构都一样, 而该论文的核心思想就是不断地去融合不同尺度上的信息, 也就是论文中说的Exchange Blocks。
从上图可以看出,HRNet首先通过两个卷积核大小为3x3步距为2的卷积层(后面接着BN以及ReLU)共下采样了4倍, 然后通过Layer1模块, 这里的Layer1其实和之前的ResNet中的Layer1类似, 就是重复堆叠Bottleneck, 注意这里的Layer1只会调整通道个数, 并不会改变特征层大小。
然后是一系列Transition以及stage结构, 每通过一个transition结构都会新增一个尺度分支, 比如transition1, 它在layer1的输出基础上通过并行两个卷积核为3x3的卷积层得到两个不同尺度分支, 即下采样4倍的尺度以及下采样8倍的尺度。在Transition2中在原来的两个尺度分支基础上再新增加一个下采样16倍的尺度。
下面介绍stage结构, 为方便理解, 以stage3为例, 对于每个尺度分支, 首先通过4个Basic Block,这个就是ResNet中的Basic Block, 然后融合不同尺度上的信息。对于每个尺度分支上的输出都是由所有分支上的输出进行融合得到的。比如对于下采样4倍分支的输出, 它是分别将下采样4倍分支的输出(不做任何处理)、下采样8倍分支的输出通过Up x2上采样2倍以及下采样16倍分支的输出通道通过Up x4上采样4倍进行相加最后通过ReLU得到下采样4倍分支的融合输出,其他分支也类似。xn表示该模块(Basic Block和Exchange Block)重复堆叠n次。
下面看一下Up和Down是如何实现的,对于所有的Up模块通过一个卷积核大小为1x1的卷积层后通过BN层最后通过Upsample直接放大n倍得到上采样后的结果(这里的上采样默认采用的是nearest最邻近插值)。Down模块相比于Up模块稍微麻烦一点, 每下采样2倍都要增加一个卷积核大小为3x3步距为2的卷积层(注意下图中Conv和Conv2d的区别, Conv2d是普通的卷积层, 而Conv包含了卷积, BN以及ReLU激活函数)。
最后需要注意的是Stage4中的最后一个Exchange Block只输出下采样4倍分支的输出(即只保留分辨率最高的特征层), 然后接上一个卷积核大小为1x1卷积核个数为17(因为coco数据集中每个人标注了17个关键点)的卷积层,最终得到的特征层(64x48x17)就是针对每个关键点的heatmap(热力图)。
预测结果(heatmap)可视化
关于预测得到的heatmap听起来比较抽象,假设输入网络预测图片的大小为256x192。为保证原图像比例, 在两侧进行padding。右侧是从预测结果也及时heatmap(64x48x17)中提取出的部分关键点对应的预测信息(64x17x1)。上面提到过, 网络最终输出的heatmap的分辨率是原图的1/4,所以高宽分别是64和48,接着对每个关键点的预测信息求最大值的位置, 即预测score最大的位置,作为预测关键点的位置,映射回原图就能得到原图上关键点的坐标。
在原论文中, 对于每个关键点并不是直接取score最大的位置(直接取score最大的位置其实也没有多大的影响)。假设对于某一关键点heatmap如下图所示, 根据寻找最大score可以找到坐标(3, 3),接着对比该点两侧(x方向), 上下两侧(y方向)的score。比如先看左右两侧, 明显右侧的score比左侧大(颜色越深,score越大), 所以最终预测的x坐标偏移了0.25, 同理上下两侧也是一样的。所以x, y的预测分别为3.25和2.75。
coco数据集中标注的17个关键点的顺序如下:
“kps”: [“nose”,”left_eye”,”right_eye”,”left_ear”,”right_ear”,”left_shoulder”,”right_shoulder”,”left_elbow”,”right_elbow”,”left_wrist”,”right_wrist”,”left_hip”,”right_hip”,”left_knee”,”right_knee”,”left_ankle”,”right_ankle”]
损失的计算
论文中说采用的是均方误差Mean Squared Error.
网络预测的最终结果是针对每个关键点的heatmap, 那么训练对应的GT又是什么呢, 根据标注信息我们知道每个关键点的坐标的(原图尺度), 接着将坐标除以4(缩放到heatmap尺度)再进行四舍五入。针对每个关键点, 先生成一张全值为0的heatmap, 然后对应关键点坐标处填充1就得到下面左侧的图片。如果直接拿左侧的heatmap作为GT去训练网络的话, 会发现网络很难收敛(可以理解为针对每个关键点只有一个正样本, 其他64x48-1个都是负样本, 正负样本及其不均匀), 为了解决这个问题一般都会以关键点坐标为中心应用一个2D的高斯分布(没有做标准化处理)得到右图所示的GT(数字是随便填充的), 利用这个GT heatmap配合网络预测的heatmap就能计算MSE损失了。
最后计算损失的时候, 并非将所有关键点的损失进行相加, 而是每个点的损失分别乘以不同的权重。下面是不同点以及对应的权重。
“kps”: [“nose”,”left_eye”,”right_eye”,”left_ear”,”right_ear”,”left_shoulder”,”right_shoulder”,”left_elbow”,”right_elbow”,”left_wrist”,”right_wrist”,”left_hip”,”right_hip”,”left_knee”,”right_knee”,”left_ankle”,”right_ankle”]
“kps_weights”: [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.2, 1.2, 1.5, 1.5, 1.0, 1.0, 1.2, 1.2, 1.5, 1.5]
评价准则
在目标检测中可以通过IoU作为预测bbox和真实bbox之间的重合程度或相似程度。在关键点检测任务中一般采用OKS(object keypoint similarity)来表示预测keypoint与真实keypoints的相似程度, 其值域在0到1之间,越靠近1越相似。
其中, i表示第i个关键点
vi表示第i个关键点的可见性,这里的vi是GT提供的, vi=0表示该点在图像外无法标注,vi=1表示虽然该点不可见但大概能猜出位置。vi=2表示该点可见。
δ(x), 当x为true时值为1, x为false时, 值为0, 通过上面的公式, OKS只计算GT中标出的点, 即vi>0的所有关键点。
di表示第i个关键点与对应GT之间的欧氏距离。
s为目标面积的平方根, 原话是:scale s which we define as the square root of the object segment area. 这里的面积应该是分割面积, 该数据在COCO数据集标注信息中都是有提供的。
ki是用来控制关键点类别i的衰减常数。这个常数是在5000张验证集上统计得到的。
数据增强
论文中采用的数据增强有:随机旋转(-45°到45°之间), 随机缩放(0.65到1.35之间)。随机水平翻转以及half body(有一定概率会对目标进行裁剪, 只保留半身关键点,上半身或者下半身)。
注意输入图片的比例。假设原始输入图片大小固定尺寸为256x192(height:width=4:3), 但预测的人体目标的高宽比不是4:3, 此时千万不要简单粗暴的拉伸到256x192。正确的方法是保存目标原比例缩放到对应尺度然后再做padding, (由于高宽比>4:3, 所以保持原比例将高缩放到256, 然后在图片width两侧padding得到256x192)。如果拥有原始图像的上下文信息的话可以直接在原图中固定height, 然后再调整width保证高:宽 = 4:3, 再重新裁剪目标并缩放到256x192。这样预测的结果才是准确的。如果直接简单粗暴的拉伸准确率会明显下降。