最近在学习显著性目标检测算法的时候发下HRNet和显著性检测具有很大的相似性,于是学习了下HRNet这个网络,写个笔记给小伙伴们参考参考。HRNet是2019年发表在CVPR上面的文章。

论文:https://arxiv.org/abs/1902.09212 代码:https://github.com/leoxiaobin/deep-high-resolution-net.pytorch

  先来看下什么是关键点检测:

android 关键点检测 关键点检测网络_数据集


  注意:HRNet是针对人体关键点检测提出的网络,一次只能检测一个个体,如果想要检测出单张图像里面的多个物体,需要先经过一个专门检测人的目标检测网络,将图中每个人的位置找出来,然后再将每个人所对应的区域通过HRNet进行预测,然后再将所得到的关键点预测对应到原图中才可以得到一张图中有多个目标的情况。

  对于人体关键点检测主要有两种方式:

  • 基于回归的方式,即直接预测每个关键点的位置。
  • 基于热力图的方式,即针对每个关键点预测一张热力图,预测出每个位置上的得分。HRNet就是基于热力图的方式。

我主要从以下几个方面介绍下HRNet:

  • 网络结构
  • 预测结果可视化
  • 损失函数
  • 评价准则
  • 数据增强和输入图像比例

  先来看下HRNet的网络结构(HRNet-32),原文中还提供了HRNet-48(其实结构都一样,只不过通道个数不一致),这里直接放的太阳花的小绿豆(很厉害的大佬)绘制的一幅图,个人感觉绘制的很清晰。

android 关键点检测 关键点检测网络_数据集_02


  网络结构很容易分析,注意里面的一些细节就行了,图中的layer1(只改变channel个数)很resnet里面的layer1很像。模型中的融合采用的都是exchange block,即都是交叉融合。网络最后的输出只会输出分辨率最高的结果。后面的输出为17是因为作者采用的是COCO数据集,而COCO数据集有17个人体关键点。

注意:实际上在原论文中的Transition2的部分只有一个卷积层,即下面框出来的部分在代码实现的时候只偶遇上图中所标的的最下面的一个卷积层:

android 关键点检测 关键点检测网络_目标检测_03


预测可视化:

  上面介绍了通过网络之后会得到每个关键点的热力图,如下图,这里仍然放一个太阳花的小绿豆绘制的一幅图。左边的图输入HRNet之后,分别提取出鼻子,左眼,右眼,左肩,右肩关键点所预测的热力图,在这些热力图上寻找score最大的位置。找到位置之后,将其映射回原图,得到最终的结果。

android 关键点检测 关键点检测网络_目标检测_04


  上面说了将热力图中得分最大的映射回原图,但是在原码中并不是这么做的,实际上是先找不得分最大的位置,然后再看该点的周围的点的得分,哪边大就向哪边偏移android 关键点检测 关键点检测网络_损失函数_05。其实直接用最大值也没多大误差。

  下面我们再来看下损失函数。采用的是均方误差损失函数。如果直接在heatmap上标记一个GT,很难训练,解决方法就是在GT的周围使用高斯分布来来扩展GT区域。

android 关键点检测 关键点检测网络_目标检测_06


  最终的损失并不是简单的每个关键点的损失相加,而是加了一个权重。

评价准则:
  在关键点检测中一一般使用OKS来表示预测的关键点和真实的关键点的相程度,取值在(0,1)之间,越大越好。
android 关键点检测 关键点检测网络_android 关键点检测_07

  • android 关键点检测 关键点检测网络_数据集_08代表第 android 关键点检测 关键点检测网络_android 关键点检测_09
  • android 关键点检测 关键点检测网络_android 关键点检测_10代表第 android 关键点检测 关键点检测网络_android 关键点检测_09
  • android 关键点检测 关键点检测网络_损失函数_12android 关键点检测 关键点检测网络_android 关键点检测_13 为 True时值为 android 关键点检测 关键点检测网络_损失函数_14
  • di为第 android 关键点检测 关键点检测网络_android 关键点检测_09
  • android 关键点检测 关键点检测网络_android 关键点检测_16
  • android 关键点检测 关键点检测网络_损失函数_17

  数据增强:

  • 随即旋转
  • 随机缩放
  • 随机水平翻转
  • half body,对目标进行一定的裁剪

  输入图像比例:高宽保持不变、