MMPose 中的 SimpleBaseline2D:ResNet 骨干与反卷积热图头的姿态估计基线全解析
2026/9/17 14:16:09 网站建设 项目流程

MMPose 中的 SimpleBaseline2D:ResNet 骨干与反卷积热图头的姿态估计基线全解析

【免费下载链接】mmposeOpenMMLab Pose Estimation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmpose

SimpleBaseline2D(ECCV 2018)是 OpenMMLab 姿态估计工具箱 MMPose 中最具代表性的 top-down 热图基线算法之一。本文以 docs/src/papers/algorithms/simplebaseline2d.md 为骨架,结合仓库中的核心实现(HeatmapHeadMSRAHeatmapcodec)、COCO 训练配置与测试用例,系统拆解该算法在 MMPose 中的完整落地方式。读完本文,你将掌握:SimpleBaseline2D 的"简单基线"设计哲学、高斯热图编解码原理、td-hm_res50_8xb64-210e_coco-256x192.py逐段配置含义,以及如何基于该基线扩展 DarkPose 等精度增强方案。

论文定位:复杂时代下的"简单基线"

SimpleBaseline2D 论文Simple baselines for human pose estimation and tracking(Xiao Bin、Wu Haiping、Wei Yichen,ECCV 2018,第 466–481 页)提出的背景是:姿态估计与姿态追踪领域在快速发展的同时,整体算法与系统复杂度也在不断上升,这使得算法分析与横向对比变得愈发困难。论文的目标是提供一组简单且有效的基线方法,用于启发新想法、统一评估口径。其原始摘要(见关联文档)明确指出:这些基线方法在多个具有挑战性的公开基准上取得了当时领先的结果。

在 MMPose 的模型库索引中,该论文被登记为算法条目SimpleBaseline2D (ECCV'2018),并在 README.md 中标注为已支持算法。仓库采用以下 BibTeX 记录其出处(保留自关联文档):

@inproceedings{xiao2018simple, title={Simple baselines for human pose estimation and tracking}, author={Xiao, Bin and Wu, Haiping and Wei, Yichen}, booktitle={Proceedings of the European conference on computer vision (ECCV)}, pages={466--481}, year={2018} }

"简单"的落点在于:不需要 Hourglass 式的反复上下采样、不需要沙漏堆叠或复杂多阶段精修,仅靠一个 ImageNet 预训练的 ResNet 骨干 + 一组反卷积(deconv)上采样层,就能逼近当时的最先进水平。这种极简结构使它天然成为后续工作(如 DarkPose、UDP 及各类新骨干)的对比基准,也使其在 MMPose 中承担着 "everything can be plugged in" 的测试平台角色。

架构解析:ResNet 骨干 + 三层反卷积头

整体数据流

SimpleBaseline2D 采用 top-down 范式:先用检测器框出人体实例,再将裁剪后的人体图像输入网络预测关键点热图。其网络结构在 MMPose 中由TopdownPoseEstimator(mmpose/models/pose_estimators/topdown.py)组装,核心链路为:

输入图像 (256x192) → ResNet 骨干(stride=32 的 C5 特征图,如 2048 通道) → HeatmapHead: 3× 反卷积(256 通道,4x4,stride 2,BN + ReLU)→ 特征图 64x48 → 1×1 卷积 → 17 通道关键点热图(64x48) → MSRAHeatmap codec 解码 → 关键点坐标 + 置信度

反卷积头:HeatmapHead

对应论文中反卷积头的实现是 mmpose/models/heads/heatmap_heads/heatmap_head.py 中的HeatmapHead类。其 docstring 明确写道:"Top-down heatmap head introduced in Simple Baselines by Xiao et al (2018). The head is composed of a few deconvolutional layers followed by a convolutional layer to generate heatmaps from low-resolution feature maps."

关键超参数及其默认值(见 heatmap_head.py):

参数默认值含义
in_channels必填骨干输出的特征通道数(ResNet-50 为 2048)
out_channels必填输出热图通道数,等于关键点数量(COCO 为 17)
deconv_out_channels(256, 256, 256)每个反卷积层的输出通道数
deconv_kernel_sizes(4, 4, 4)每个反卷积层的卷积核大小
conv_out_channels/conv_kernel_sizesNone反卷积与最终卷积之间的中间卷积层,None表示省略
final_layerdict(kernel_size=1)最终输出层的配置(1x1 卷积)
lossKeypointMSELoss(use_target_weight=True)训练损失
decoderNone解码 codec 配置

_make_deconv_layers(heatmap_head.py)揭示了反卷积层的构造细节:每层使用stride=2的转置卷积,内核为 4 时padding=1, output_padding=0,内核为 3 时padding=1, output_padding=1,内核为 2 时padding=0, output_padding=0;每个反卷积后紧跟 BatchNorm 与 ReLU。默认 4x4 反卷积将 1/32 分辨率的特征图逐级放大 2 倍,三层后整体上采样 8 倍,最终得到约 1/4 输入分辨率的 64x48 热图(对应 256x192 输入)。

forward方法(heatmap_head.py)实现了feats[-1]→ deconv → conv → final 的完整前向,而default_init_cfg规定了对Conv2d/ConvTranspose2d使用std=0.001的 Normal 初始化、对 BatchNorm 使用 1 的 Constant 初始化。

训练目标:MSRAHeatmap 高斯热图编解码

SimpleBaseline2D 的训练目标是将关键点坐标编码为高斯热图,对应的 codec 是 mmpose/codecs/msra_heatmap.py 中的MSRAHeatmap。该类在 docstring 中同样引用了本论文:"Represent keypoints as heatmaps via MSRA approach. See the paper Simple Baselines for Human Pose Estimation and Tracking by Xiao et al (2018)"

encode阶段(msra_heatmap.py)的要点:

  • 只支持单实例编码(keypoints.shape[0] == 1,符合 top-down 裁剪后单人的前提);
  • 将关键点坐标按scale_factor = input_size / heatmap_size缩放到热图空间;
  • 调用generate_gaussian_heatmaps(见 mmpose/codecs/utils/gaussian_heatmap.py)以sigma为标准差生成高斯峰,同时产出keypoint_weights用于损失加权;
  • unbiased=True时改用generate_unbiased_gaussian_heatmaps,即 DarkPose 的无偏编码。

decode阶段(msra_heatmap.py)则通过get_heatmap_maximum取热图最大值位置得到初始坐标,再调用refine_keypoints(非 DarkPose)或refine_keypoints_dark(DarkPose,可配blur_kernel_size,默认 11,对应经验公式sigma = 0.3*((ks-1)*0.5-1)+0.8)做亚像素精修,最后乘以scale_factor还原到输入图像空间。

配置全解析:td-hm_res50_8xb64-210e_coco-256x192.py

模型库中该算法在 COCO 上的标准配置为 configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-256x192.py,逐段含义如下。

训练计划与优化器

_Base_ = ['../../../_base_/default_runtime.py'] train_cfg = dict(max_epochs=210, val_interval=10) optim_wrapper = dict(optimizer=dict(type='Adam', lr=5e-4)) param_scheduler = [ dict(type='LinearLR', begin=0, end=500, start_factor=0.001, by_epoch=False), # warm-up dict(type='MultiStepLR', begin=0, end=210, milestones=[170, 200], gamma=0.1, by_epoch=True) ] auto_scale_lr = dict(base_batch_size=512) default_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))
  • 训练 210 个 epoch,每 10 个 epoch 在验证集上评估一次;
  • 使用 Adam 优化器,初始学习率 5e-4;
  • 前 500 iter 线性 warm-up(起始因子 0.001),随后在第 170、200 epoch 处将学习率乘以 0.1(MultiStepLR);
  • auto_scale_lr以 512 为基准 batch size 自动缩放学习率;
  • checkpoint 钩子按coco/AP指标(越大越好)保存最优权重。

codec 与模型

codec = dict( type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2) model = dict( type='TopdownPoseEstimator', data_preprocessor=dict( type='PoseDataPreprocessor', mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], bgr_to_rgb=True), backbone=dict( type='ResNet', depth=50, init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50')), head=dict( type='HeatmapHead', in_channels=2048, out_channels=17, loss=dict(type='KeypointMSELoss', use_target_weight=True), decoder=codec), test_cfg=dict(flip_test=True, flip_mode='heatmap', shift_heatmap=True))
  • MSRAHeatmap编码器:输入 192x256、热图 48x64、高斯sigma=2
  • 骨干为 ImageNet 预训练的 ResNet-50;
  • HeatmapHead输入 2048 通道、输出 17 通道(COCO 人体 17 关键点),损失为带目标权重的KeypointMSELoss
  • test_cfg开启翻转测试(flip test)TTA:推理时将原图与水平翻转图分别前向,融合两者热图。该逻辑在 heatmap_head.py 的predict中实现——利用flip_heatmaps(mmpose/models/utils/tta.py)按flip_indices对齐关键点索引并对翻转热图做平移补偿,最后取平均。

数据流水线

train_pipeline = [ dict(type='LoadImage'), dict(type='GetBBoxCenterScale'), dict(type='RandomFlip', direction='horizontal'), dict(type='RandomHalfBody'), dict(type='RandomBBoxTransform'), dict(type='TopdownAffine', input_size=codec['input_size']), dict(type='GenerateTarget', encoder=codec), dict(type='PackPoseInputs') ] val_pipeline = [ dict(type='LoadImage'), dict(type='GetBBoxCenterScale'), dict(type='TopdownAffine', input_size=codec['input_size']), dict(type='PackPoseInputs') ]

训练时依次执行:随机水平翻转、随机半身(RandomHalfBody,当可见关键点多集中于半身时按概率只用半身训练)、随机边界框扰动、仿射变换到 192x256、由MSRAHeatmap编码器生成高斯热图目标。验证/测试流水线不包含任何随机增强。

数据加载与评估

  • train_dataloader:batch_size 64、2 workers,COCOperson_keypoints_train2017.json
  • val_dataloader:batch_size 32,使用检测器预生成的COCO_val2017_detections_AP_H_56_person.json边界框(test_mode=True,即用外部检测框而非模型自身);
  • 评估器为CocoMetric,读取person_keypoints_val2017.json计算 AP/AR 系列指标。COCO 数据集基础配置见base/datasets/coco.py。

训练与测试实操

在完成数据集准备(结构为data/coco/,含train2017/val2017/person_keypoints_train2017.json等标注)后,可参考 docs/en/user_guides/train_and_test.md 执行:

# 单卡训练 python tools/train.py configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-256x192.py # 8 卡分布式训练(bash tools/dist_train.sh <config> <gpu_num>) bash tools/dist_train.sh configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-256x192.py 8 # 测试评估 python tools/test.py configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-256x192.py <checkpoint路径>

训练日志与权重由default_hooks管理,最优模型依据验证集 COCO AP 自动保存。

模型库基准结果

configs/body_2d_keypoint/topdown_heatmap/coco/resnet_coco.md 收录了 SimpleBaseline2D 各规格在 COCO val2017 上的指标(评测使用在 COCO val2017 上人体 AP 为 56.4 的检测器):

架构输入尺寸APAP⁵⁰AP⁷⁵ARAR⁵⁰
pose_resnet_50256x1920.7180.8980.7960.7740.934
pose_resnet_50384x2880.7310.9000.7990.7820.937
pose_resnet_101256x1920.7280.9040.8090.7830.942
pose_resnet_101384x2880.7490.9060.8170.7990.941
pose_resnet_152256x1920.7360.9040.8180.7910.942
pose_resnet_152384x2880.7500.9080.8210.8000.942

其中 384x288 输入对应 td-hm_res101_8xb32-210e_coco-384x288.py 等更高分辨率配置。同一目录下的 resnet_coco.yml 以结构化元数据记录这些条目,其README字段即指向本文对应的论文页 docs/src/papers/algorithms/simplebaseline2d.md,形成"论文页 → 模型页 → 配置文件"的完整引用链。

此外,仓库还提供带可见性预测头的变体 td-hm-vis_res50_8xb64-210e_coco-aic-256x192-merge.py(使用 COCO+AIC 联合训练,256x192 输入下 AP 0.729),用于跟踪场景中对关键点可见性的估计。

精度增强变体:DarkPose 与 Wo-Deconv

DarkPose 无偏编解码

td-hm_res50_dark-8xb64-210e_coco-256x192.py 在相同结构上将 codec 改为:

codec = dict( type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2, unbiased=True)

unbiased=True使编码端采用无偏高斯热图、解码端采用 DarkPose 的亚像素精修,在不动网络结构的前提下显著提升精度。这是"基线算法 + 后处理/编解码增强"可独立叠加的典型范例。

移除反卷积的变体

由于反卷积层是 SimpleBaseline2D 特有的上采样部件,仓库中还存在刻意去掉该部件的对比配置,用于验证上采样方式的影响,例如 SIMCC 流水线的 simcc_mobilenetv2_wo-deconv-8xb64-210e_coco-256x192.py 与 ViTPose 的td-hm_ViTPose-base-simple_*系列。在HeatmapHead中,当deconv_out_channels为空时反卷积层被替换为nn.Identity()(heatmap_head.py),体现代码对两种路线的统一支持。

测试用例验证

仓库通过 tests/test_codecs/test_msra_heatmap.py 对MSRAHeatmap的编解码行为做了完整验证,覆盖encodedecode、闭环验证(encode → decode 坐标还原)与异常参数检查(如input_size=(192, 256), heatmap_size=(48, 64), sigma=2.0的标准实例化),可据此确认上述配置的合法性与编解码一致性。反卷积头的构造与预测行为则由 tests/test_models/test_heads/test_heatmap_head.py 等用例保障。

小结

SimpleBaseline2D 在 MMPose 中的价值远超"一篇论文的复现":它以最简结构——ResNet 预训练骨干 + 三层反卷积 + 高斯热图 MSE 回归——构成了 top-down 热图流派的可复现基准。理解其MSRAHeatmapcodec 与HeatmapHead的设计后,你可以自如地在同一框架内替换骨干(ResNet-50/101/152、SEResNet、ResNeSt 等,见 configs/body_2d_keypoint/topdown_heatmap/coco 下的同类配置)、叠加 DarkPose 无偏编解码、调整反卷积结构或切换输入分辨率,从而快速验证新的研究想法——这正是论文标题中"simple baselines"对领域研究与工程实践的持续贡献。

【免费下载链接】mmposeOpenMMLab Pose Estimation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmpose

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询