最近在学习显著性目标检测算法的时候发下HRNet和显著性检测具有很大的相似性,于是学习了下HRNet这个网络,写个笔记给小伙伴们参考参考。HRNet是2019年发表在CVPR上面的文章。
论文:https://arxiv.org/abs/1902.09212
代码:https://github.com/leoxiaobin/deep-high-resolution-net.pytorch
先来看下什么是关键点检测:
注意:HRNet是针对人体关键点检测提出的网络,一次只能检测一个个体,如果想要检测出单张图像里面的多个物体,需要先经过一个专门检测人的目标检测网络,将图中每个人的位置找出来,然后再将每个人所对应的区域通过HRNet进行预测,然后再将所得到的关键点预测对应到原图中才可以得到一张图中有多个目标的情况。
对于人体关键点检测主要有两种方式:
- 基于回归的方式,即直接预测每个关键点的位置。
- 基于热力图的方式,即针对每个关键点预测一张热力图,预测出每个位置上的得分。HRNet就是基于热力图的方式。
我主要从以下几个方面介绍下HRNet:
- 网络结构
- 预测结果可视化
- 损失函数
- 评价准则
- 数据增强和输入图像比例
先来看下HRNet的网络结构(HRNet-32),原文中还提供了HRNet-48(其实结构都一样,只不过通道个数不一致),这里直接放的太阳花的小绿豆(很厉害的大佬)绘制的一幅图,个人感觉绘制的很清晰。
网络结构很容易分析,注意里面的一些细节就行了,图中的layer1(只改变channel个数)很resnet里面的layer1很像。模型中的融合采用的都是exchange block,即都是交叉融合。网络最后的输出只会输出分辨率最高的结果。后面的输出为17是因为作者采用的是COCO数据集,而COCO数据集有17个人体关键点。
注意:实际上在原论文中的Transition2的部分只有一个卷积层,即下面框出来的部分在代码实现的时候只偶遇上图中所标的的最下面的一个卷积层:
预测可视化:
上面介绍了通过网络之后会得到每个关键点的热力图,如下图,这里仍然放一个太阳花的小绿豆绘制的一幅图。左边的图输入HRNet之后,分别提取出鼻子,左眼,右眼,左肩,右肩关键点所预测的热力图,在这些热力图上寻找score最大的位置。找到位置之后,将其映射回原图,得到最终的结果。
上面说了将热力图中得分最大的映射回原图,但是在原码中并不是这么做的,实际上是先找不得分最大的位置,然后再看该点的周围的点的得分,哪边大就向哪边偏移
1
4
\frac{1}{4}
41。其实直接用最大值也没多大误差。
下面我们再来看下损失函数。采用的是均方误差损失函数。如果直接在heatmap上标记一个GT,很难训练,解决方法就是在GT的周围使用高斯分布来来扩展GT区域。
最终的损失并不是简单的每个关键点的损失相加,而是加了一个权重。
评价准则:
在关键点检测中一一般使用OKS来表示预测的关键点和真实的关键点的相程度,取值在(0,1)之间,越大越好。
O
K
S
=
∑
i
[
e
−
d
i
2
/
2
s
2
k
i
2
⋅
δ
(
v
i
>
0
)
]
∑
i
[
δ
(
v
i
>
0
)
]
O K S=\frac{\sum_i\left[e^{-d_i^2 / 2 s^2 k_i^2} \cdot \delta\left(v_i>0\right)\right]}{\sum_i\left[\delta\left(v_i>0\right)\right]}
OKS=∑i[δ(vi>0)]∑i[e−di2/2s2ki2⋅δ(vi>0)]
- i i i代表第 i \mathrm{i} i 个关键点
- v i vi vi代表第 i \mathrm{i} i 个关键点的可见性,这里的 vi是由GT提供
- δ ( x ) \delta(x) δ(x) 当 x x x 为 True时值为 1 , x 1, \mathrm{x} 1,x 为 False时值为 0
- di为第 i \mathrm{i} i 个预测关键点与对应GT之间的欧氏距离
- s \mathrm{s} s 为目标面积的平方根
- k i \mathrm{ki} ki 是用来控制关键点类别i的衰减常数
数据增强:
- 随即旋转
- 随机缩放
- 随机水平翻转
- half body,对目标进行一定的裁剪
输入图像比例:高宽保持不变、