MMPose 中的 RSN 人体关键点估计:Topdown 热图配置的完整解析与 COCO 基准结果
【免费下载链接】mmposeOpenMMLab Pose Estimation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmpose
本文围绕 MMPose 仓库中 RSN(Residual Steps Network)在 COCO 数据集上的人体 2D 关键点估计展开,基于 configs/body_2d_keypoint/topdown_heatmap/coco/rsn_coco.md 及其关联的 4 份训练配置,系统讲解 RSN 主干的网络结构与源码实现、MSPNHead 多头热图预测机制、MegviiHeatmap 多尺度标签编码、完整训练/测试配置参数,以及 COCO val2017 上的官方基准结果,帮助读者能够独立复现、微调并深入理解该算法在 MMPose 中的落地细节。
一、算法背景与 COCO 基准结果
RSN 出自 ECCV 2020 论文 "Learning Delicate Local Representations for Multi-Person Pose Estimation"(Cai et al.),其核心思想是通过"残差步骤块"(Residual Steps Block, RSB)在极小感受野内堆叠多级局部卷积,学习精细的局部特征表示,再配合小时玻璃(hourglass-like)的多阶段下采样/上采样结构,同时保持高分辨率特征输出与细粒度局部细节。原文引用见 rsn_coco.md 中的 BibTeX:
@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} }在 COCO 数据集(ECCV 2014,"Microsoft COCO: Common Objects in Context")上,使用 human AP 为 56.4 的人体检测器(bbox_file 指向COCO_val2017_detections_AP_H_56_person.json),官方在 COCO val2017 上报告的基准结果如下(表格继承自 rsn_coco.md):
| 模型 | 输入尺寸 | AP | AP50 | AP75 | AR | AR50 | 配置文件 |
|---|---|---|---|---|---|---|---|
| RSN-18 | 256x192 | 0.704 | 0.887 | 0.781 | 0.773 | 0.927 | td-hm_rsn18 |
| RSN-50 | 256x192 | 0.724 | 0.894 | 0.799 | 0.790 | 0.935 | td-hm_rsn50 |
| 2xRSN-50 | 256x192 | 0.748 | 0.900 | 0.821 | 0.810 | 0.939 | td-hm_2xrsn50 |
| 3xRSN-50 | 256x192 | 0.750 | 0.900 | 0.824 | 0.814 | 0.941 | td-hm_3xrsn50 |
从结果可以读出两个规律:其一,主干加深(RSN-18 → RSN-50,AP 0.704 → 0.724)收益明显;其二,增加小时玻璃阶段数(RSN-50 → 2xRSN-50 → 3xRSN-50)带来约 2 个点的进一步提升,但 3xRSN-50 相对 2xRSN-50 的增益(0.002)已经很小,计算开销却随阶段数线性增长,选型时可按精度/速度权衡。预训练权重(ckpt)与训练日志(log)托管在 OpenMMLab 资源站上,原文档 rsn_coco.md 中每行附有对应的下载地址。
二、RSN 主干的源码实现
RSN 主干实现在 mmpose/models/backbones/rsn.py 中,由以下组件自底向上组成:
- ResNet_top(rsn.py#L499):轻量前置卷积,7x7、stride=2 卷积 + 3x3 MaxPool,输出通道数为
res_top_channels(默认 64),是小时玻璃结构的输入起点。 - RSB(Residual Steps Block)(rsn.py#L14):RSN 的核心算子。先用 1x1 卷积将通道扩展为
num_steps * branch_channels并切分为num_steps份,然后做num_steps步 3x3 卷积,每一步的 j 路特征都依赖同一步的第 j-1 路特征与上一步第 j 路特征(inputs = inputs + outputs[i - 1][j],见 rsn.py#L101-L115 的 forward 循环),形成"残差步骤"式的局部分支细化,最后拼接num_steps个对角分支输出,经 1x1 卷积回缩通道并与 identity 相加。默认num_steps=4、expand_times=26。 - Downsample_module / Upsample_module(rsn.py#L128、rsn.py#L361):各由 4 个单位(
num_units=4)构成。下采样模块中相邻 unit 通道数翻倍、空间尺寸减半,共输出 4 个不同尺度的中间特征(64/128/256/512 对应 1/2、1/4、1/8、1/16 分辨率);上采样模块对 4 个尺度分别做 1x1 卷积并沿单位链路上采样相加,最终恢复出 4 个unit_channels(默认 256)通道的多尺度特征图。 - Single_stage_RSN(rsn.py#L435):一次"下采样 + 上采样"即一个完整的小时玻璃阶段。
- RSN(rsn.py#L529):注册于
MODELS的总入口,堆叠num_stages个 Single_stage_RSN。forward 中前一个阶段的 cross 特征作为下一阶段的输入,非首阶段通过has_skip=True接收前一阶段上采样模块生成的 skip1/skip2 残差连接(见 rsn.py#L613-L628)。每个阶段输出 4 个尺度的特征元组,即配置中level_indices=[0, 1, 2, 3]所引用的 4 个层级。
这与论文中的命名约定一致:RSN-18 对应num_blocks=[2, 2, 2, 2],RSN-50 对应num_blocks=[3, 4, 6, 3](每个下采样 unit 中 RSB 的数量);"2x/3x" 前缀对应num_stages=2/3,即小时玻璃重复的级数。num_stages越大,多尺度特征在更深层被反复重构,细节与上下文融合越充分,但参数量与耗时也随之增长。
三、MSPNHead 多头预测与损失设计
头部使用 MSPNHead(Multi-Scale Pose Network Head,实现在 mspn_head.py)。它以 backbone 每阶段输出的 4 个尺度特征为输入,每个尺度由一个PredictHeatmap分支独立上采样到out_shape=(64, 48)并预测 17 通道热图;该头部还支持论文中的PRM(Pose Refine Machine)(mspn_head.py#L23),即对预测热图做全局路径(1x1 全局池化 + MLP)与局部路径(深度可分离卷积)联合的置信度精化。
4 份配置中的损失写法完全一致,均为每阶段/每 unit 的KeypointMSELoss(权重 0.25)共 3 个 + 1 个KeypointOHKMMSELoss(权重 1.0,OHKM 即 Outlier-robust Huber-style Keypoint MSELoss,用于抑制离群点热图对梯度的影响);2x/3x 版本按阶段数整体复制该损失组(loss=(...) * 2/* 3)。level_indices则声明每个 unit 应消费哪个层级的 backbone 特征:
- RSN-18 / RSN-50(单阶段):
level_indices=[0, 1, 2, 3] - 2xRSN-50(两阶段,且 codec 多一个 kernel 15 层级):
level_indices=[0, 1, 2, 3] + [1, 2, 3, 4] - 3xRSN-50(三阶段):
level_indices=[0, 1, 2, 3] * 2 + [1, 2, 3, 4]
四、MegviiHeatmap:多 kernel 热力图标签编码
训练 pipeline 中GenerateTarget(multilevel=True, encoder=codec)使用 MegviiHeatmap 编解码器(实现位于 mmpose/codecs/megvii_heatmap.py),它按配置中的kernel_sizes列表为每个层级生成不同高斯核宽度的热图目标:
- RSN-18 / RSN-50:
kernel_sizes = [11, 9, 7, 5](4 个层级,对应 4 个 unit 特征) - 2xRSN-50 / 3xRSN-50:
kernel_sizes = [15, 11, 9, 7, 5](多出一个更粗的 kernel,与第二/三阶段更深层特征匹配)
粗尺度特征配宽高斯核、细尺度特征配窄高斯核,使每个 PredictHeatmap 分支都在与自身分辨率匹配的标签下训练。解码端则取codec[-1](kernel=5 的精细层级)作为最终热图,用于推理时把热图反解为关键点坐标。
五、训练配置逐项解读
以 td-hm_rsn50_8xb32-210e_coco-256x192.py 为代表(RSN-18 差异在优化器与调度,下文单独说明),关键配置如下:
| 配置项 | 取值 | 说明 |
|---|---|---|
train_cfg | max_epochs=210, val_interval=10 | 训练 210 轮,每 10 轮验证一次 |
optim_wrapper | Adam,lr=5e-3(RSN-18 为2e-2) | 浅网用更激进的学习率 |
param_scheduler | LinearLR warmup 500 步(start_factor=0.001)+ MultiStepLR,milestones=[170, 200](RSN-18 为 [170, 190, 200]),gamma=0.1 | 与论文配方一致 |
auto_scale_lr | base_batch_size=256 | 按实际 batch 线性缩放学习率,8x32=256 为基准 |
codec | MegviiHeatmap,input=(192, 256),heatmap=(48, 64),kernel_sizes=[11, 9, 7, 5] | 多尺度高斯热图标签 |
backbone | RSN,unit_channels=256, num_stages=1, num_units=4, num_blocks=[3, 4, 6, 3], num_steps=4 | 对应 RSN-50 主干 |
head | MSPNHead,out_channels=17(COCO 17 关键点),num_stages/num_units=1/4 | 4 个尺度各出一组热图 |
test_cfg | flip_test=True, flip_mode='heatmap', shift_heatmap=False | 测试时热图级水平翻转增强 |
| 数据增强 | RandomFlip、RandomHalfBody、RandomBBoxTransform、TopdownAffine | 标准 topdown 增强组合 |
fp16 | dict(loss_scale='dynamic') | 半精度训练,动态损失缩放 |
| 评估 | CocoMetric,nms_mode='none' | COCO 标准 PCK/AP 指标 |
数据部分:训练使用annotations/person_keypoints_train2017.json;验证/测试使用annotations/person_keypoints_val2017.json,并通过bbox_file指定人体检测结果data/coco/person_detection_results/COCO_val2017_detections_AP_H_56_person.json——这正是结果表注中 "detector having human AP of 56.4" 的来源,即 topdown 结果的可复现性依赖该固定检测器。数据集准备可参考 prepare_datasets.md。
训练与测试命令
在已安装 MMPose 并准备好 COCO 数据(data_root='data/coco/')后:
# 单卡训练 RSN-50 python tools/train.py configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_rsn50_8xb32-210e_coco-256x192.py # 多卡训练(8 卡) bash tools/dist_train.sh 8 configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_rsn50_8xb32-210e_coco-256x192.py # 测试指定 checkpoint python tools/test.py configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_rsn50_8xb32-210e_coco-256x192.py <checkpoint_path>其中 tools/train.py、tools/test.py 为标准入口,多卡脚本为 tools/dist_train.sh / tools/dist_test.sh。default_hooks中checkpoint=dict(save_best='coco/AP', rule='greater')会自动按验证集 COCO AP 保存最优权重。
六、模型选型与扩展建议
- 精度优先:选择 3xRSN-50(AP 0.750)或 2xRSN-50(AP 0.748,耗时约为其 2/3 量级,从源码结构看计算量随
num_stages线性增长); - 速度敏感:RSN-18(AP 0.704)主干最浅,
num_blocks全为 2,是部署场景的合理起点; - 自定义扩展:可调整
num_steps、unit_channels、expand_times(均见 RSN 构造函数 的默认值)或 codec 的kernel_sizes组合,但需保持num_units == len(num_blocks)(源码中有断言约束)以及level_indices与阶段/层级数一致; - 验证可复现性:注意结果表的前提是人体检测器 AP 为 56.4,若更换 bbox_file,同配置的 AP 会随之波动,这属于 topdown 评测的固有属性。
七、相关文件索引
| 类别 | 路径 |
|---|---|
| 结果文档 | configs/body_2d_keypoint/topdown_heatmap/coco/rsn_coco.md |
| RSN-18 配置 | configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_rsn18_8xb32-210e_coco-256x192.py |
| RSN-50 配置 | configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_rsn50_8xb32-210e_coco-256x192.py |
| 2xRSN-50 配置 | configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_2xrsn50_8xb32-210e_coco-256x192.py |
| 3xRSN-50 配置 | configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_3xrsn50_8xb32-210e_coco-256x192.py |
| RSN 主干实现 | mmpose/models/backbones/rsn.py |
| MSPNHead 实现 | mmpose/models/heads/heatmap_heads/mspn_head.py |
| MegviiHeatmap 编解码器 | mmpose/codecs/megvii_heatmap.py |
| 主干测试 | tests/test_models/test_backbones |
【免费下载链接】mmposeOpenMMLab Pose Estimation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmpose
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考