
MMPose 中的 RSN 骨干网络残差步进网络与精细局部表示的多人体姿态估计实践【免费下载链接】mmposeOpenMMLab Pose Estimation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmpose导读本文围绕 ECCV 2020 论文《Learning Delicate Local Representations for Multi-Person Pose Estimation》提出的Residual Steps NetworkRSN残差步进网络结合 OpenMMLab MMPose 仓库中的真实源码与配置系统讲解其核心思想同尺寸层内特征聚合、Pose Refine Machine 注意力机制、模块化实现RSB / Downsample / Upsample / Multi-stage 结构以及在 COCO 人体关键点任务上的完整训练、测试与调参方案。读完本文你将掌握 RSN 的底层设计原理、如何在 MMPose 中复用其骨架与 MSPN 多头结构、如何理解并调整num_stages、num_blocks、kernel_sizes等关键超参数并能直接复现仓库内置的 rsn18/rsn50/2xrsn50/3xrsn50 四套实验。一、算法背景与论文核心思想RSN 是字节跳动ByteDance团队在 2020 年发表于 ECCV 的多人姿态估计方法论文作者为 Yuanhao Cai、Zhicheng Wang、Zhengxiong Luo 等人。该工作赢得了COCO Keypoint Challenge 2019 冠军并在未使用额外训练数据和预训练模型的情况下在 COCO 与 MPII 两个基准上取得了当时领先的结果。论文原摘要指出原文见 docs/src/papers/backbones/rsn.mdIn this paper, we propose a novel method called Residual Steps Network (RSN). RSN aggregates features with the same spatial size (Intra-level features) efficiently to obtain delicate local representations, which retain rich low-level spatial information and result in precise keypoint localization. Additionally, we observe the output features contribute differently to final performance. To tackle this problem, we propose an efficient attention mechanism - Pose Refine Machine (PRM) to make a trade-off between local and global representations in output features and further refine the keypoint locations.其核心贡献可以归纳为两点精细局部表示Delicate Local Representations不同于常规 HRNet 式的多分辨率并行结构RSN 着重于聚合空间尺寸相同的层内特征Intra-level features。通过多步残差聚合保留丰富的低层空间信息从而获得更精确的关键点定位能力。Pose Refine MachinePRM论文观察到骨干输出的不同特征对最终性能的贡献不同因此设计了一种轻量注意力机制在输出特征的局部表示与全局表示之间做权衡trade-off进一步修正关键点位置。论文报告的结果来自原文档单模型在 COCO test-dev 上达到78.6在 MPII test 上达到93.0集成模型在 COCO test-dev 上达到79.2在 COCO test-challenge 数据集上达到77.1。原始论文引用信息如下源自 rsn.md可供学术引用misc{cai2020learning, title{Learning Delicate Local Representations for Multi-Person Pose Estimation}, author{Yuanhao Cai and Zhicheng Wang and Zhengxiong Luo and Binyi Yin and Angang Du and Haoqian Wang and Xinyu Zhou and Erjin Zhou and Xiangyu Zhang and Jian Sun}, year{2020}, eprint{2003.04030}, archivePrefix{arXiv}, primaryClass{cs.CV} }二、RSN 的模块化源码实现剖析MMPose 将 RSN 完整实现为可注册的骨干网络源码位于 mmpose/models/backbones/rsn.py共 640 行通过MODELS.register_module()注册为RSN继承自BaseBackbone。整个实现由六个核心模块自底向上堆叠而成。1. RSBResidual Steps Block——层内特征聚合的最小单元RSB类定义在 rsn.py#L14-L125是 RSN 与普通 ResNet 残差块最大的区别所在。其构造参数如下参数默认值说明in_channels必填输入通道数out_channels必填输出通道数num_steps4RSB 内的步进数step 数量构造时断言 1stride1残差块步长downsampleNone恒等分支上的降采样模块with_cpFalse是否启用 checkpoint省显存norm_cfgdict(typeBN)归一化层配置expand_times26通道扩展倍数res_top_channels64ResNet_top 输出的通道数用于计算分支通道其前向计算的核心逻辑rsn.py#L93-L125是步进式的层内聚合def forward(self, x): identity x x self.conv_bn_relu1(x) # 1x1 卷积将通道扩展为 num_steps * branch_channels spx torch.split(x, self.branch_channels, 1) # 按步数切分为 num_steps 份 for i in range(self.num_steps): for j in range(i 1): if j 0: inputs spx[i] else: inputs outputs[i][j - 1] if i j: inputs inputs outputs[i - 1][j] # 层内(同尺寸)特征逐步相加聚合 outputs[i].append(module_i_j(inputs)) outs.append(outputs[i][i]) out torch.cat(tuple(outs), 1) # 各步输出拼接 out self.conv_bn3(out) # 1x1 卷积还原通道 out out identity # 残差连接 out self.relu(out) return out从源码结构可以推断RSB 将输入在通道维切分成num_steps份构建一个类似阶梯的计算图——第i步会聚合前i步的所有中间结果同尺寸特征相加最后将所有步的输出在通道维拼接并经1x1卷积融合。这正是论文中聚合同空间尺寸特征以获得精细局部表示的直接代码映射多步内聚合让浅层空间细节得以保留并逐级细化。注意branch_channels的计算方式branch_channels in_channels * expand_times // res_top_channels默认expand_times26、res_top_channels64当in_channels64时分支通道数为64 * 26 / 64 26因此conv_bn_relu1输出num_steps * 26通道。2. ResNet_top——输入降采样模块ResNet_toprsn.py#L499-L525作为网络的入口对输入图像做快速降采样self.top nn.Sequential( ConvModule(3, channels, kernel_size7, stride2, padding3, norm_cfgnorm_cfg, inplaceTrue), MaxPool2d(kernel_size3, stride2, padding1))即一个7x7步长 2 的卷积加一个3x3步长 2 的 MaxPool将输入分辨率降为原来的 1/4并输出res_top_channels默认 64个通道。3. Downsample_module——编码端下采样单元组Downsample_modulersn.py#L128-L239由num_units默认 4个下采样单元组成每个单元内部是若干RSB的堆叠num_blocks列表控制每个单元内 RSB 数量从第 2 个单元起步长设为 2 进行空间降采样通道数按in_channels * pow(2, i)递增。其前向rsn.py#L228-L239接收当前特征x以及上一级上采样模块回传的两组 skip 特征def forward(self, x, skip1, skip2): out list() for i in range(self.num_units): x module_i(x) if self.has_skip: x x skip1[i] skip2[i] # 上一级上采样的跨级反馈 out.append(x) out.reverse() # 反转供上采样端从小到大消费 return tuple(out)has_skipTrue表示该阶段具备来自前一个上采样模块的跨阶段跳跃连接即多阶段之间的粗到精细化信号这正是 PRM 思想在结构上的体现之一。4. Upsample_module / Upsample_unit——解码端上采样单元组Upsample_modulersn.py#L361-L432由num_units个Upsample_unitrsn.py#L242-L358组成。每个Upsample_unit的关键行为rsn.py#L335-L358in_skip用1x1卷积对齐来自下采样端的通道数当ind 0时将上一个单元的输出up_x通过F.interpolate(..., modebilinear, align_cornersTrue)双线性上采样到当前尺寸并相加形成逐级融合当gen_skipTrue时生成两组 skip 特征out_skip1、out_skip2回传给后续下采样模块当ind num_units - 1且gen_cross_convTrue时通过cross_conv生成跨阶段特征供下一个阶段作为输入同时也供头部使用。5. Single_stage_RSN——单阶段沙漏式结构Single_stage_RSNrsn.py#L435-L496把 Downsample 与 Upsample 组装成一个完整的下采样—上采样阶段self.downsample Downsample_module(RSB, num_blocks, num_steps, num_units, has_skip, norm_cfg, in_channels, expand_times) self.upsample Upsample_module(unit_channels, num_units, gen_skip, gen_cross_conv, norm_cfg, in_channels)6. RSN——多阶段级联的整体骨架顶层RSN类rsn.py#L528-L640的构造参数即配置文件可覆盖的全部口径参数默认值说明unit_channels256上采样单元内通道数num_stages4多阶段 RSN 的阶段数断言 0num_units4单个阶段内下/上采样单元数断言 1且需等于len(num_blocks)num_blocks[2, 2, 2, 2]每个下采样单元内的 RSB 数量num_steps4RSB 内步进数断言 1norm_cfgdict(typeBN)归一化配置res_top_channels64ResNet_top 输出通道expand_times26RSB 通道扩展倍数init_cfgKaiming Constant Normal默认初始化策略Conv2d 用 KaimingBN/GroupNorm 置 1Linear 用 std0.01 的 Normal多阶段级联的关键逻辑在构造函数rsn.py#L612-L628for i in range(self.num_stages): has_skip (i ! 0) # 首阶段无跨阶段 skip gen_skip gen_cross_conv (i ! self.num_stages - 1) # 末阶段不再产生 skip / cross self.multi_stage_rsn.append(Single_stage_RSN(...))前向rsn.py#L630-L640将每个阶段的输出特征收集为out_feats列表返回供MSPNHead消费def forward(self, x): out_feats [] skip1 skip2 None x self.top(x) for i in range(self.num_stages): out, skip1, skip2, x self.multi_stage_rsni out_feats.append(out) return out_feats源码 docstring 给出了一个可验证的前向示例rsn.py#L562-L576RSN(num_stages2, num_units2, num_blocks[2,2])对(1, 3, 511, 511)输入会输出 4 组特征形状分别为(1, 256, 64, 64)、(1, 256, 128, 128)、(1, 256, 64, 64)、(1, 256, 128, 128)——即每个阶段产生与num_units数量相同的多尺度特征。三、配套头部MSPNHead 与 PRM 注意力机制RSN 骨架通常与MSPNHead多阶段多单元热图头部源自 MSPN 论文、被 RSN 复用配合使用实现在 mmpose/models/heads/heatmap_heads/mspn_head.py#L170。其类 docstring 明确指出该头部introduced in Multi-Stage Pose estimation Network (MSPN) by Li et al (2019), and used by Residual Steps Networks (RSN) by Cai et al (2020)。MSPNHead 的关键参数参数默认值说明num_stages4阶段数需与 RSN 的num_stages一致num_units4每阶段单元数out_shape(64, 48)输出热图尺寸H, Wunit_channels256输入通道数out_channels17关键点类别数COCO 人体为 17use_prmFalse是否启用 Pose Refine MachinePRMlevel_indices[]每个 stage/unit 输出特征对应到哪一尺度的热图标签长度须等于num_stages * num_unitslossKeypointMSELoss各 stage/unit 的损失配置可为列表逐单元指定decoderNone从网络输出解码关键点坐标的编解码器配置其中use_prm正是论文中Pose Refine Machine注意力机制的开关默认为False。构造时会校验len(level_indices) ! num_stages * num_units以及损失列表长度与num_stages * num_units的一致性mspn_head.py#L225-L245从源码结构可以推断该头部为每个阶段、每个单元都维护独立的PredictHeatmap预测层与独立的损失模块从而实现多阶段多尺度监督。四、COCO 配置文件逐项精读仓库为 RSN 提供了四套可直接运行的 COCO 配置位于 configs/body_2d_keypoint/topdown_heatmap/coco/配置骨架规模num_stagesnum_blocks学习率td-hm_rsn18_8xb32-210e_coco-256x192.pyRSN-181[2, 2, 2, 2]2e-2td-hm_rsn50_8xb32-210e_coco-256x192.pyRSN-501[3, 4, 6, 3]5e-3td-hm_2xrsn50_8xb32-210e_coco-256x192.py2xRSN-502[3, 4, 6, 3]5e-3td-hm_3xrsn50_8xb32-210e_coco-256x192.py3xRSN-503[3, 4, 6, 3]5e-31. 训练运行时与优化器所有配置统一继承_base_下的default_runtime.py并约定max_epochs210、val_interval10优化器统一使用 Adam其中rsn18 的 lr 为2e-2rsn50 及多阶段版本为5e-3参数规模越大、学习率相应调小。学习率调度采用两段式以 rsn18 为例param_scheduler [ dict(typeLinearLR, begin0, end500, start_factor0.001, by_epochFalse), # 前 500 iter 线性预热 dict(typeMultiStepLR, begin0, end210, milestones[170, 190, 200], gamma0.1, by_epochTrue) ]即先做 500 步迭代级线性 warm-up再在 170/190/200 epochrsn50 系为 170/200按gamma0.1分步衰减。同时配置了auto_scale_lr dict(base_batch_size256)实际训练时框架会根据真实 batch size 自动等比缩放学习率默认钩子default_hooks按coco/AP指标保存最优 checkpoint。2. Megvii 多尺度热图编解码codecRSN 系列使用 Megvii旷视式多尺度高斯热图编解码对应实现为 mmpose/codecs/megvii_heatmap.py 中的MegviiHeatmap通过KEYPOINT_CODECS注册。该 codec 的关键点是kernel_size为多尺度高斯核列表编码时对每个尺度热图执行cv2.GaussianBlur(heatmaps[k], kernel_size, 0)megvii_heatmap.py#L100-L101为不同层级的输出特征匹配不同粗细的高斯核rsn18 / rsn50单阶段kernel_sizes [11, 9, 7, 5]2xrsn50 / 3xrsn50多阶段kernel_sizes [15, 11, 9, 7, 5]阶段变多、监督层级变多多出一个更粗的15核统一配置为input_size(192, 256)、heatmap_size(48, 64)即输入 192x256输出热图降采样 4 倍为 48x64。训练管线中通过dict(typeGenerateTarget, multilevelTrue, encodercodec)生成多层级监督目标这正是 MSPNHead 中level_indices所索引的标签集合。3. 骨架与头部配置以 rsn50 单阶段为例model dict( typeTopdownPoseEstimator, data_preprocessordict( typePoseDataPreprocessor, mean[123.675, 116.28, 103.53], std[58.395, 57.12, 57.375], bgr_to_rgbTrue), backbonedict( typeRSN, unit_channels256, num_stages1, num_units4, num_blocks[3, 4, 6, 3], num_steps4, norm_cfgdict(typeBN), ), headdict( typeMSPNHead, out_shape(64, 48), unit_channels256, out_channels17, num_stages1, num_units4, norm_cfgdict(typeBN), level_indices[0, 1, 2, 3], loss[ dict(typeKeypointMSELoss, use_target_weightTrue, loss_weight0.25) ] * 3 [ dict(typeKeypointOHKMMSELoss, use_target_weightTrue, loss_weight1.) ], decodercodec[-1]), test_cfgdict( flip_testTrue, flip_modeheatmap, shift_heatmapFalse, ))几个值得展开的细节level_indices的取值规律单阶段rsn18/rsn50为[0, 1, 2, 3]对应 4 个单元的 4 个特征层2 阶段为[0, 1, 2, 3] [1, 2, 3, 4]第二个阶段的最深层输出对应第 5 级标签3 阶段为[0, 1, 2, 3] * 2 [1, 2, 3, 4]。混合损失设计前 3 个单元使用KeypointMSELoss权重0.25最后 1 个单元使用KeypointOHKMMSELoss权重1.0——即最终输出层用OHKM在线难例挖掘 MSE强化监督中间层级用普通 MSE 辅助监督。多阶段版本把这一损失块整体乘以阶段数* 2/* 3。测试增强flip_testTrue、flip_modeheatmap即测试时对输入做水平翻转并融合两张热图shift_heatmapFalse。精度优化配置末尾统一开启fp16 dict(loss_scaledynamic)动态损失缩放混合精度训练。4. 数据管线与评测数据部分为标准的 top-down 流程data_modetopdown、CocoDataset、data_rootdata/coco/。训练管线依次为LoadImage→GetBBoxCenterScale→RandomFlip(horizontal)→RandomHalfBody→RandomBBoxTransform→TopdownAffine(input_size192x256)→GenerateTarget(multilevelTrue)→PackPoseInputs验证/测试管线去掉增强并加入外部检测框文件COCO_val2017_detections_AP_H_56_person.json人体检测器 AP 56.4 的检测结果。评测器为CocoMetric且因为该配置没有显式启用 OKS-NMSnms_modenone在复现指标时需保持该设置与结果表一致。五、训练、测试与推理实战1. 训练使用仓库根目录的 tools/train.py 启动训练单卡或多卡--launcher方式见仓库说明8 卡环境可直接用8xb32语义复现python tools/train.py configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_rsn50_8xb32-210e_coco-256x192.py多卡训练可参考 tools/dist_train.shbash tools/dist_train.sh configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_rsn50_8xb32-210e_coco-256x192.py 8训练前请确保已按 docs/zh_cn/user_guides/prepare_datasets.md 准备好 COCO 数据集data/coco/下含annotations/person_keypoints_train2017.json等并在data/coco/person_detection_results/放置验证用检测框文件。2. 测试使用 tools/test.py 在验证集上评测python tools/test.py configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_rsn50_8xb32-210e_coco-256x192.py \ checkpoint.pth --out result.pkl训练过程中default_hooks.checkpoint会按save_bestcoco/AP自动保存最优权重离线测试时传入该权重即可复现下表指标。CocoMetric会输出 AP / AP50 / AP75 / AR 等完整指标。3. 推理最快捷的方式是使用 MMPose 的 Inferencer 加载任一 RSN 配置与权重做单人图片推理例如 demo/inferencer_demo.py 配合 COCO 全身/人体姿态模型若需检测器 top-down 姿态估计的完整多人流程可参考 demo/topdown_demo_with_mmdet.py 与 demo/mmdetection_cfg/ 下的人体检测器配置。六、COCO 基准结果与模型选型建议仓库在 configs/body_2d_keypoint/topdown_heatmap/coco/rsn_coco.md 中公布了 COCO val2017检测器人体 AP 56.4上的复现结果原文数值如下ArchInput SizeAPAP50AP75ARAR50rsn_18256x1920.7040.8870.7810.7730.927rsn_50256x1920.7240.8940.7990.7900.9352xrsn_50256x1920.7480.9000.8210.8100.9393xrsn_50256x1920.7500.9000.8240.8140.941选型建议基于上述实测数据的合理推断追求性价比单阶段 RSN-18 即可达到 AP 0.704显存占用和训练成本最低适合快速验证与轻量部署单模型精度优先RSN-50 比 RSN-18 提升约 2.0 AP0.704 → 0.724是精度/成本平衡点多阶段堆叠收益递减2 阶段 RSN-50 提升约 2.4 AP0.724 → 0.748幅度最大3 阶段仅再提升 0.2 AP0.748 → 0.750而参数量与显存继续翻倍——若算力受限2 阶段是性价比较高的配置。这恰好与论文输出特征对最终性能贡献不同的观察一致也是 PRM 机制要解决的问题。七、RSN 的使用限制与调参注意事项阶段一致性约束RSN.num_stages、MSPNHead.num_stages必须保持一致且num_units len(num_blocks)MSPNHead.level_indices的长度必须等于num_stages * num_units源码中有显式校验见 mspn_head.py#L225-L228修改阶段数时务必同步更新这两处。多阶段监督标签阶段数增加时MegviiHeatmap的kernel_sizes建议同步扩展仓库在 2/3 阶段配置中加入了15的粗高斯核并为每个阶段在loss列表中复制对应损失块。显存与学习率多阶段 RSN 显存开销接近线性增长若显存不足可优先尝试降低batch_size并依靠auto_scale_lr自动缩放学习率或探索启用with_cpcheckpoint 重计算节省显存。编解码器依赖RSN 系列依赖MegviiHeatmap多尺度热图编解码与MSPNHead的多层级监督设计直接替换为普通MSRAHeatmapHeatmapHead会丢失其设计意图如需完整复现论文设定建议保留仓库配置的组合。PRM 开关MSPNHead.use_prm参数默认False提供了论文中 Pose Refine Machine 的实现入口仓库内置的四套 COCO 配置未显式开启读者可在自定义实验中将其置为True进行消融对比。八、延伸阅读骨架完整实现mmpose/models/backbones/rsn.py配套头部实现mmpose/models/heads/heatmap_heads/mspn_head.py编解码器实现mmpose/codecs/megvii_heatmap.py全部 RSN COCO 配置与结果configs/body_2d_keypoint/topdown_heatmap/coco/训练与测试入口tools/train.py、tools/test.py、tools/dist_train.sh官方结果表configs/body_2d_keypoint/topdown_heatmap/coco/rsn_coco.md【免费下载链接】mmposeOpenMMLab Pose Estimation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmpose创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考