HRNet网络简介

这篇具有很好参考价值的文章主要介绍了HRNet网络简介。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

论文名称: Deep High-Resolution Representation Learning for Human Pose Estimation
论文下载地址:https://arxiv.org/abs/1902.09212
官方源码地址:https://github.com/leoxiaobin/deep-high-resolution-net.pytorch

在bilibili上的视频讲解:https://www.bilibili.com/video/BV1bB4y1y7qP



0 前言

这篇文章是由中国科学技术大学和亚洲微软研究院在2019年共同发表的。这篇文章中的HRNet(High-Resolution Net)是针对2D人体姿态估计(Human Pose Estimation或Keypoint Detection)任务提出的,并且该网络主要是针对单一个体的姿态评估(即输入网络的图像中应该只有一个人体目标)。人体姿态估计在现今的应用场景也比较多,比如说人体行为动作识别,人机交互(比如人作出某种动作可以触发系统执行某些任务),动画制作(比如根据人体的关键点信息生成对应卡通人物的动作)等等。
hrnet,深度学习,关键点检测,深度学习,pytorch,关键点检测,人体姿态估计,HRNet对于Human Pose Estimation任务,现在基于深度学习的方法主要有两种:

  1. 基于regressing的方式,即直接预测每个关键点的位置坐标。
  2. 基于heatmap的方式,即针对每个关键点预测一张热力图(预测出现在每个位置上的分数)。

当前检测效果最好的一些方法基本都是基于heatmap的,所以HRNet也是采用基于heatmap的方式。


1 HRNet网络结构

下图是我根据阅读项目源码绘制的关于HRNet-W32的模型结构简图,在论文中除了提出HRNet-W32外还有一个HRNet-W48的版本,两者区别仅仅在每个模块所采用的通道个数不同,网络的整体结构都是一样的。而该论文的核心思想就是不断地去融合不同尺度上的信息,也就是论文中所说的Exchange Blocks

hrnet,深度学习,关键点检测,深度学习,pytorch,关键点检测,人体姿态估计,HRNet
通过上图可以看出,HRNet首先通过两个卷积核大小为3x3步距为2的卷积层(后面都跟有BN以及ReLU)共下采样了4倍。然后通过Layer1模块,这里的Layer1其实和之前讲的ResNet中的Layer1类似,就是重复堆叠Bottleneck,注意这里的Layer1只会调整通道个数,并不会改变特征层大小。下面是实现Layer1时所使用的代码。

# Stage1
downsample = nn.Sequential(
    nn.Conv2d(64, 256, kernel_size=1, stride=1, bias=False),
    nn.BatchNorm2d(256, momentum=BN_MOMENTUM)
)
self.layer1 = nn.Sequential(
    Bottleneck(64, 64, downsample=downsample),
    Bottleneck(256, 64),
    Bottleneck(256, 64),
    Bottleneck(256, 64)
)

接着通过一系列Transition结构以及Stage结构,每通过一个Transition结构都会新增一个尺度分支。比如说Transition1,它在layer1的输出基础上通过并行两个卷积核大小为3x3的卷积层得到两个不同的尺度分支,即下采样4倍的尺度以及下采样8倍的尺度。在Transition2中在原来的两个尺度分支基础上再新加一个下采样16倍的尺度,注意这里是直接在下采样8倍的尺度基础上通过一个卷积核大小为3x3步距为2的卷积层得到下采样16倍的尺度。如果有阅读过原论文的小伙伴肯定会有些疑惑,因为在论文的图1中,给出的Transition2应该是通过融合不同尺度的特征层得到的(下图用红色矩形框框出的部分)。但根据源码的实现过程确实就和我上面图中画的一样,就一个3x3的卷积层没做不同尺度的融合,包括我看其他代码仓库实现的HRNet都是如此。大家也可以自己看看源码对比一下。

hrnet,深度学习,关键点检测,深度学习,pytorch,关键点检测,人体姿态估计,HRNet
简单介绍完Transition结构后,在来说说网络中最重要的Stage结构。为了方便大家理解,这里以Stage3为例,对于每个尺度分支,首先通过4个Basic Block,没错就是ResNet里的Basic Block,然后融合不同尺度上的信息。对于每个尺度分支上的输出都是由所有分支上的输出进行融合得到的。比如说对于下采样4倍分支的输出,它是分别将下采样4倍分支的输出(不做任何处理)下采样8倍分支的输出通过Up x2上采样2倍 以及下采样16倍分支的输出通过Up x4上采样4倍进行相加最后通过ReLU得到下采样4倍分支的融合输出。其他分支也是类似的,下图画的已经非常清楚了。图中右上角的x4表示该模块(Basic BlockExchange Block)要重复堆叠4次。

hrnet,深度学习,关键点检测,深度学习,pytorch,关键点检测,人体姿态估计,HRNet

接着再来聊聊图中的UpDown究竟是怎么实现的,对于所有的Up模块就是通过一个卷积核大小为1x1的卷积层然后BN层最后通过Upsample直接放大n倍得到上采样后的结果(这里的上采样默认采用的是nearest最邻近插值)。Down模块相比于Up稍微麻烦点,每下采样2倍都要增加一个卷积核大小为3x3步距为2的卷积层(注意下图中ConvConv2d的区别,Conv2d就是普通的卷积层,而Conv包含了卷积、BN以及ReLU激活函数)。

hrnet,深度学习,关键点检测,深度学习,pytorch,关键点检测,人体姿态估计,HRNet
最后,需要注意的是在Stage4中的最后一个Exchange Block只输出下采样4倍分支的输出(即只保留分辨率最高的特征层),然后接上一个卷积核大小为1x1卷积核个数为17(因为COCO数据集中对每个人标注了17个关键点)的卷积层。最终得到的特征层(64x48x17)就是针对每个关键点的heatmap(热力图)。

hrnet,深度学习,关键点检测,深度学习,pytorch,关键点检测,人体姿态估计,HRNet


2 预测结果(heatmap)的可视化

关于预测得到的heatmap(热力图)听起来挺抽象的,为了方便大家理解,我画了下面这幅图。首先,左边是输入网络的预测图片,大小为256x192,为了保证原图像比例,在两侧进行了padding。右侧是我从预测结果,也就是heatmap(64x48x17)中提取出的部分关键点对应的预测信息(48x17x1)。上面有提到过,网络最终输出的heatmap分辨率是原图的 1 4 \frac{1}{4} 41,所以高宽分别对应的是64和48,接着对每个关键点对应的预测信息求最大值的位置,即预测score最大的位置,作为预测关键点的位置,映射回原图就能得到原图上关键点的坐标(下图有画出每个预测关键点对应原图的位置)。
hrnet,深度学习,关键点检测,深度学习,pytorch,关键点检测,人体姿态估计,HRNet
但在原论文中,对于每个关键点并不是直接取score最大的位置(如果为了方便直接取其实也没太大影响)。在原论文的4.1章节中有提到:

Each keypoint location is predicted by adjusting the highest heatvalue location with a quarter offset in the direction from the highest response to the second highest response.

光看文字其实还是不太明白,下面是源码中对应的实现,其中coords是每个关键点对应预测score最大的位置:

for n in range(coords.shape[0]):
    for p in range(coords.shape[1]):
        hm = batch_heatmaps[n][p]
        px = int(math.floor(coords[n][p][0] + 0.5))
        py = int(math.floor(coords[n][p][1] + 0.5))
        if 1 < px < heatmap_width-1 and 1 < py < heatmap_height-1:
            diff = np.array(
                [
                    hm[py][px+1] - hm[py][px-1],
                    hm[py+1][px]-hm[py-1][px]
                ]
            )
            coords[n][p] += np.sign(diff) * .25

如果看不懂的话可以再看下我下面画的这副图。假设对于某一关键点的预测heatmap如下所示,根据寻找最大score可以找到坐标(3, 3)点,接着分别对比该点左右两侧(x方向),上下两侧(y方向)的score。比如说先看左右两侧,明显右侧的score比左侧的大(蓝色越深代表score越大),所以最终预测的x坐标向右侧偏移0.25故最终x=3.25,同理上侧的score比下侧大,所以y坐标向上偏移0.25故最终y=2.75。
hrnet,深度学习,关键点检测,深度学习,pytorch,关键点检测,人体姿态估计,HRNet

关于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"]

最后把每个关键点绘制在原图上,就得到如下图所示的结果。

hrnet,深度学习,关键点检测,深度学习,pytorch,关键点检测,人体姿态估计,HRNet


3 损失的计算

在论文第3章Heatmap estimation中作者说训练采用的损失就是均方误差Mean Squared Error

The loss function, defined as the mean squared error, is applied for comparing the predicted heatmaps and the groundtruth heatmaps. The groundtruth heatmpas are generated by applying 2D Gaussian with standard deviation of 1 pixel centered on the grouptruth location of each keypoint.

通过前面讲的内容我们知道网络预测的最终结果是针对每个关键点的heatmap,那训练时对应的GT又是什么呢。根据标注信息我们是可以得知每个关键点的坐标的(原图尺度),接着将坐标都除以4(缩放到heatmap尺度)在进行四舍五入。针对每个关键点,我们先生成一张值全为0的heatmap,然后将对应关键点坐标处填充1就得到下面左侧的图片。如果直接拿左侧的heatmap作为GT去训练网络的话,你会发现网络很难收敛(可以理解为针对每个关键点只有一个点为正样本,其他64x48-1个点都是负样本,正负样本极度不均),为了解决这个问题一般会以关键点坐标为中心应用一个2D的高斯分布(没有做标准化处理)得到如右图所示的GT(随手画的不必深究)。利用这个GT heatmap配合网络预测的heatmap就能计算MSE损失了。

hrnet,深度学习,关键点检测,深度学习,pytorch,关键点检测,人体姿态估计,HRNet
下面这幅图是某张真实训练样本(左侧)对应nose关键点的GT heatmap(右侧)。
hrnet,深度学习,关键点检测,深度学习,pytorch,关键点检测,人体姿态估计,HRNet

我们知道如何计算每个关键点对应的损失后还需要留意一个小细节。代码中在计算总损失时,并不是直接把每个关键点的损失进行相加,而是在相加前对于每个点的损失分别乘上不同的权重。下面给出了每个关键点的名称以及所对应的权重。

"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]

4 评价准则

在目标检测(Object Detection)任务中可以通过IoU(Intersection over Union)作为预测bbox和真实bbox之间的重合程度或相似程度。在关键点检测(Keypoint Detection)任务中一般用OKS(Object Keypoint Similarity)来表示预测keypoints与真实keypoints的相似程度,其值域在0到1之间,越靠近1表示相似度越高。在MS COCO官网中有详细介绍OKS指标,详情参考: https://cocodataset.org/#keypoints-eval

O K S = ∑ i [ e − d i 2 / 2 s 2 k i 2 ⋅ δ ( v i > 0 ) ] ∑ i [ δ ( v i > 0 ) ] OKS = \frac{{\textstyle \sum_{i}^{}} [e^{{-d_i^2}/{2s^2}{k_i^2}} \cdot \delta(v_i>0)]}{ {\textstyle \sum_{i}^{}} [\delta(v_i>0)]} OKS=i[δ(vi>0)]i[edi2/2s2ki2δ(vi>0)]
其中:

  • i i i代表第i个关键点。
  • v i v_i vi代表第i个关键点的可见性,这里的 v i v_i vi是由GT提供的。 v i = 0 v_i=0 vi=0表示该点一般是在图像外无法标注, v i = 1 v_i=1 vi=1表示虽然该点不可见但大概能猜测出位置(比如人侧着站时虽然有一只耳朵被挡住了,但大概也能猜出位置), v i = 2 v_i=2 vi=2表示该点可见。
  • δ ( x ) \delta(x) δ(x),当 x x x为True时值为1, x x x为False时值为0。通过上面公式可知,OKS只计算GT中标注出的点,即 v i > 0 v_i>0 vi>0的所有关键点。
  • d i d_i di为第i个预测关键点与对应GT之间的欧氏距离。
  • s s s为目标面积的平方根,原话:scale s which we define as the square root of the object segment area,这里的面积应该指的是分割面积。该数据在COCO数据集标注信息中都是有提供的。
  • k i k_i ki是用来控制关键点类别i的衰减常数,原话:κi is a per-keypont constant that controls falloff,这个常数是在验证集(5000张)上统计得到的,具体如何计算 k i k_i ki参考官网中1.3. Tuning OKS的介绍。

5 其他

如果想要学习HRNet代码的话,不太建议直接去读官方源码。因为环境配置有些小问题,而且看起来令人头大。建议看我提供的HRNet仓库代码,我对原仓库代码做了一些修改,并加了很多注释,学习起来会更方便点。先给出链接,这周周末会上传代码:https://github.com/WZMIAOMIAO/deep-learning-for-image-processing/tree/master/pytorch_keypoint/HRNet

5.1 数据增强

在论文中作者采用的数据增强有:随机旋转(在 − 4 5 ∘ -45^{\circ} 45 4 5 ∘ 45^{\circ} 45之间),随机缩放(在0.65到1.35之间),随机水平翻转以及half body(有一定概率会对目标进行裁剪,只保留半身关键点,上半身或者下半身)。在源码中,作者主要是通过仿射变换来实现的以上操作,如果对仿射变换不太了解看代码会比较吃力。

5.2 注意输入图片比例

假设对于输入网络图片固定尺寸是256x192(height : width = 4 : 3),但要预测的人体目标的高宽比不是4 : 3,此时千万不要直接简单粗暴的拉伸到256x192(如下图左侧所示),正确的方法是保持目标原比例缩放到对应尺度然后再进行相应的padding(如下图中间所示,由于目标的height : width > 4 : 3,所以保持原比例将height缩放到256,然后在图片width两测进行padding得到256x192)。如果拥有原始图像的上下文信息的话可以直接在原图中固定height(目标height : width > 4 : 3的情况)然后调整width保证height : width = 4 : 3,再重新裁剪目标并缩放到256x192(如下图右侧所示)。这样预测的结果才是准确的。如果直接简单粗暴的拉伸目标,准确率会明显下降。因为作者源码中训练网络时始终保证目标的比例不变,那么我们在预测时也要保证相同的处理方式,即保证目标比例不变。之前我在COCO2017 val数据上对齐论文精度时,就是由于没有注意这个细节,导致精度差了十几个点(⊙﹏⊙)。

hrnet,深度学习,关键点检测,深度学习,pytorch,关键点检测,人体姿态估计,HRNet文章来源地址https://www.toymoban.com/news/detail-816816.html

到了这里,关于HRNet网络简介的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 会Python如何学习C#的几个关键点

    Python和C#都是常用的编程语言,但两者之间存在一些重要的区别。如果你已经掌握了Python并希望学习C#,以下是几个关键点: 面向对象编程(OOP):C#是一种严格的面向对象编程语言,而Python则具有更灵活的OOP实现。在学习C#之前,建议先理解面向对象编程的基础概念,如类、

    2023年04月12日
    浏览(27)
  • 机器学习笔记 - 基于MobileNetV2的迁移学习训练关键点检测器

            StanfordExtra数据集包含12000张狗的图像以及关键点和分割图图。 GitHub - benjiebob/StanfordExtra:12k标记的野外狗实例,带有2D关键点和分割。我们的 ECCV 2020 论文发布的数据集:谁把狗排除在外?3D 动物重建,循环中期望最大化。 https://github.com/benjiebob/StanfordExtra      

    2024年02月10日
    浏览(36)
  • 机器学习笔记 - 探索PaddlePaddle框架的对象检测、分割和关键点检测

            PaddlePaddle(PArallel Distributed Deep LEarning)是百度于2016年发布的开源深度学习框架。它为各种机器学习任务提供了统一的平台。 但是最近的基准测试显示 PaddlePaddle 是潜在的领跑者,其基准速度超过了其更知名的竞争对手。          PaddlePaddle 与 PyTorch 或 Tensorf

    2024年02月13日
    浏览(44)
  • 基于骨骼关键点的动作识别(OpenMMlab学习笔记,附PYSKL相关代码演示)

    骨骼动作识别 是 视频理解 领域的一项任务 1.1 视频数据的多种模态 RGB:使用最广,包含信息最多,从RGB可以得到Flow、Skeleton。但是处理需要较大的计算量 Flow:光流,主要包含运动信息,处理方式与RGB相同,一般用3D卷积 Audio:使用不多 Skeleton :骨骼关键点序列数据,即人

    2024年02月03日
    浏览(33)
  • 2D人脸关键点转3D人脸关键点的映射~头部姿态笔记

    对通过相机参数计算图像上的二维坐标到三维坐标的映射进行简单探讨。         学习的话直接看他们的就好,我仅是拾人牙慧,拿GPT写给自己看的,图也是直接搬运的别人画的,以下链接有很完善的理论研究和代码提供。 https://medium.com/@susanne.thierfelder/head-pose-estimation

    2024年02月04日
    浏览(34)
  • mmpose关键点(四):优化关键点模型(原理与代码讲解,持续更新)

    在工程中,模型的运行速度与精度是同样重要的,本文中,我会运用不同的方法去优化比较模型的性能,希望能给大家带来一些实用的trick与经验。 有关键点检测相关经验的同学应该知道,关键点主流方法分为Heatmap-based与Regression-based。 其主要区别在于监督信息的不同,Hea

    2024年02月08日
    浏览(48)
  • 关键点数据增强

    1.关键点平移数据增强 2.关键点旋转数据增强 3.关键点可视化 4.json2txt(用YOLOV8进行关键点训练) 5.划分训练集和验证集

    2024年02月09日
    浏览(31)
  • opencv-人脸关键点定位

    2024年02月12日
    浏览(41)
  • Mediapipe人脸关键点检测

    MediaPipe是由google制作的开源的、跨平台的机器学习框架,可以将一些模型部署到不同的平台和设备上使用的同时,也能保住检测速度。 从图中可以发现,能在Python上实现的功能包括人脸检测(Face Detection)、人脸关键点(Face Mesh),手部关键点(Hands)等。利用C++能实现更丰富

    2024年02月02日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包