MMPose 中基于 Swin Transformer 的 Top-down 人体姿态估计基线:COCO 上的配置、训练与源码剖析
【免费下载链接】mmposeOpenMMLab Pose Estimation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmpose
本文以 MMPose 仓库中configs/body_2d_keypoint/topdown_heatmap/coco/swin_coco.md这一模型文档为主体,系统讲解如何在 COCO 数据集上复现 SimpleBaseline2D + Swin Transformer(Tiny/Base/Large)的 Top-down 热图人体姿态估计基线:包括完整的关键字配置(优化器、学习率策略、Codec、数据管线)、COCO val2017 基准成绩表、训练/测试命令,并结合仓库源码剖析SwinTransformer主干的窗口注意力实现与预训练权重转换机制。读完本文,你可以直接修改并运行这组配置,并理解每个超参数背后的实现依据。
一、模型定位与 COCO val2017 基准结果
该模型文档对应的算法组合是:
- 算法框架:SimpleBaseline2D(ECCV 2018),即 Top-down 两阶段方案——先用人体检测器给出人体框,再对每个人体裁剪框独立估计关键点;
- 主干网络:Swin Transformer(ICCV 2021),层级式移位窗口 Transformer;
- 特征聚合:FPN(CVPR 2017,Swin 内部的 Patch Merging 起到类似多尺度聚合作用);
- 数据集:COCO 2017(ECCV 2014)。
文档给出的实验前提为:在 COCO val2017 上使用一个人体检测 AP 为 56.4 的检测器(对应配置中的预提取 bbox 文件),各规模模型的结果如下:
| 模型 | 输入尺寸 | AP | AP50 | AP75 | AR | AR50 | 配置文件 |
|---|---|---|---|---|---|---|---|
| pose_swin_t | 256x192 | 0.724 | 0.901 | 0.806 | 0.782 | 0.940 | td-hm_swin-t-p4-w7_8xb32-210e_coco-256x192.py |
| pose_swin_b | 256x192 | 0.737 | 0.904 | 0.820 | 0.794 | 0.942 | td-hm_swin-b-p4-w7_8xb32-210e_coco-256x192.py |
| pose_swin_b | 384x288 | 0.759 | 0.910 | 0.832 | 0.811 | 0.946 | td-hm_swin-b-p4-w7_8xb32-210e_coco-384x288.py |
| pose_swin_l | 256x192 | 0.743 | 0.906 | 0.821 | 0.798 | 0.943 | td-hm_swin-l-p4-w7_8xb32-210e_coco-256x192.py |
| pose_swin_l | 384x288 | 0.763 | 0.912 | 0.830 | 0.814 | 0.949 | td-hm_swin-l-p4-w7_8xb32-210e_coco-384x288.py |
从结果看,三个趋势明确:模型规模增大(t→b→l)带来约 1.9 个点的 AP 提升;输入分辨率从 256x192 提到 384x288,b/l 分别再提升约 2.2 个点和 2.0 个点。原模型文档同时提供了各模型的 checkpoint 与训练日志下载链接(官方 openmmlab 资源站),此处按仓库内文件组织引用上述配置路径。
二、配置全解:以 swin-t 256x192 为例
以 td-hm_swin-t-p4-w7_8xb32-210e_coco-256x192.py 为例,配置继承自 default_runtime.py(提供默认 hooks、logger、可视化后端等运行时项),核心内容可分为运行时、优化器、学习率策略、模型、数据与评估六块。
2.1 运行时与优化器
# runtime train_cfg = dict(max_epochs=210, val_interval=10) # optimizer optim_wrapper = dict(optimizer=dict(type='Adam', lr=5e-4)) # learning policy 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) ] # automatically scaling LR based on the actual training batch size auto_scale_lr = dict(base_batch_size=256) # hooks default_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))要点说明:
max_epochs=210与文件名中的210e对应;每 10 个 epoch 验证一次;- 优化器为 Adam,初始学习率
5e-4; - 学习率策略采用「500 步线性 warm-up(从 0.001 倍升到 1 倍)+ MultiStepLR(170/200 epoch 各衰减 10 倍)」;
auto_scale_lr以 256 为基准批量按实际批量线性缩放学习率——配置名义批量为8 卡 x batch 32 = 256,单机 8 卡训练时学习率无需手动调整;- checkpoint hook 以
coco/AP越大越优为准则保存最佳权重。
值得注意的是,swin-l 配置(td-hm_swin-l-p4-w7_8xb32-210e_coco-256x192.py)与 t/b 不同,改用 AdamW 并带参数分组衰减:
optim_wrapper = dict( optimizer=dict(type='AdamW', lr=5e-4, betas=(0.9, 0.999), weight_decay=0.01), paramwise_cfg=dict( custom_keys={ 'absolute_pos_embed': dict(decay_mult=0.), 'relative_position_bias_table': dict(decay_mult=0.), 'norm': dict(decay_mult=0.) }))即对绝对位置编码、相对位置偏置表和所有 norm 层关闭权重衰减——这是 Transformer 类模型常用的参数分组正则策略,而 t/b 两个较小的配置没有做此分组(使用 Adam)。
2.2 Codec:MSRAHeatmap
codec = dict( type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)input_size=(192, 256)为 [w, h] 顺序,即 192x256(宽 x 高)的人体裁剪输入;384x288 系列配置中该值相应增大;heatmap_size=(48, 64)为输入尺寸的 1/4,与主干末层特征分辨率一致;sigma=2是高斯热图的标准差。
其实现位于 msra_heatmap.py:MSRAHeatmap.encode将原始关键点坐标除以scale_factor(input_size / heatmap_size)映射到热图空间后,调用generate_gaussian_heatmaps生成 (K, H, W) 形状的高斯热图及逐关键点权重keypoint_weights;decode阶段则对预测热图取最大值得到坐标。该 Codec 支持unbiased=True(DarkPose 的无偏热图),本文基线未开启。
2.3 模型结构
norm_cfg = dict(type='SyncBN', requires_grad=True) 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='SwinTransformer', embed_dims=96, depths=[2, 2, 6, 2], num_heads=[3, 6, 12, 24], window_size=7, mlp_ratio=4, qkv_bias=True, qk_scale=None, drop_rate=0., attn_drop_rate=0., drop_path_rate=0.2, patch_norm=True, out_indices=(3, ), with_cp=False, convert_weights=True, init_cfg=dict( type='Pretrained', checkpoint='.../swin_tiny_patch4_window7_224.pth')), head=dict( type='HeatmapHead', in_channels=768, 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, ))结构解读:
TopdownPoseEstimator是 Top-down 方案的估计器包装,串联 backbone 与 head;data_preprocessor使用 ImageNet 均值/方差归一化并做 BGR→RGB 转换(加载的 Swin 预训练权重为 ImageNet 训练);- 三个规模的主干参数差异如下(其余超参一致:
patch_size=4、window_size=7、mlp_ratio=4、out_indices=(3,)):
| 规模 | embed_dims | depths | num_heads | drop_path_rate | head.in_channels | 预训练权重 |
|---|---|---|---|---|---|---|
| swin-t | 96 | [2, 2, 6, 2] | [3, 6, 12, 24] | 0.2 | 768 | ImageNet-1K 224 (tiny_patch4_window7) |
| swin-b | 128 | [2, 2, 18, 2] | [4, 8, 16, 32] | 0.3 | 1024 | ImageNet-22K 224 (base_patch4_window7_22k) |
| swin-l | 192 | [2, 2, 18, 2] | [6, 12, 24, 48] | 0.5 | 1536 | ImageNet-22K 224 (base_patch4_window7_22k) |
out_indices=(3,)表示只取第 4 个 stage 的输出(通道数为embed_dims * 2^3,即 768/1024/1536,与 head 的in_channels严格对应);HeatmapHead输出 17 通道(COCO 17 关键点)热图,损失为KeypointMSELoss(use_target_weight=True),即按 MSRA 论文的可见性权重做逐关键点加权 MSE;decoder=codec使 head 复用同一个 MSRAHeatmap 完成推理解码;- 测试期开启
flip_test(heatmap 模式翻转测试)和shift_heatmap(热图中心偏移 1 像素的亚像素精化),这两项是 Top-down 热图模型的常见免训练增强。
2.4 数据管线与数据加载
dataset_type = 'CocoDataset' data_mode = 'topdown' data_root = 'data/coco/' 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') ]训练管线包含随机水平翻转、随机半身体、随机框变换(RandomBBoxTransform)三类增强,TopdownAffine将人体框仿射到 codec 输入尺寸,GenerateTarget用 MSRAHeatmap 编码热图标签。验证管线无增强。
数据加载器的关键点:
- 训练集:
annotations/person_keypoints_train2017.json+train2017/图像,batch_size=32; - 验证/测试集:
annotations/person_keypoints_val2017.json,并指定预提取的人体检测结果bbox_file='data/coco/person_detection_results/COCO_val2017_detections_AP_H_56_person.json'——这正是结果表所述"检测器 AP 56.4"的来源。Top-down 评估使用该固定 bbox 文件可保证不同方法在相同检测结果下可比; - 评估器为
CocoMetric,按 COCO 关键点协议计算 AP/AR。
三、源码剖析:SwinTransformer 主干在 MMPose 中的实现
主干实现位于 swin.py,注册名为SwinTransformer。以下选取与本配置直接相关的实现细节。
3.1 层级化结构与 stage 组装
SwinTransformer.__init__(约 L523 起)按depths依次构建 4 个 stage:
for i in range(num_layers): if i < num_layers - 1: downsample = PatchMerging( in_channels=in_channels, out_channels=2 * in_channels, stride=strides[i + 1], norm_cfg=norm_cfg if patch_norm else None, init_cfg=None) else: downsample = None stage = SwinBlockSequence(embed_dims=in_channels, num_heads=num_heads[i], feedforward_channels=mlp_ratio * in_channels, depth=depths[i], window_size=window_size, ...) self.stages.append(stage) if downsample: in_channels = downsample.out_channels- 第一个 stage 使用非重叠卷积做 patch 嵌入(断言
strides[0] == patch_size),之后每个 stage 之间用PatchMerging做 2x 下采样并把通道数翻倍;因此num_features = [embed_dims * 2**i],第 4 stage 输出通道数正好是配置中 head 的in_channels; forward(约 L721 起)依次经过各 stage,仅对out_indices指定的 stage 输出做norm+ 重排成 (B, C, H, W)——配置取(3,),故只有第 4 个 stage 的 1/32 分辨率特征被送给 head;drop_path_rate通过torch.linspace(0, drop_path_rate, total_depth)在全部 Transformer 块间线性递增分配,这解释了 t/b/l 分别设置 0.2/0.3/0.5 的随机深度衰减率的原因:模型越深,正则越强。
3.2 窗口注意力与移位窗口
WindowMSA(约 L23 起)实现带相对位置偏置的窗口内多头自注意力:relative_position_bias_table形状为(2*Wh-1) * (2*Ww-1), num_heads,配合预计算索引relative_position_index查表得到偏置;ShiftWindowMSA(约 L128 起)先F.pad到窗口整数倍,再对移位分支执行torch.roll循环移位,并构建 6 区域注意力掩码(attn_mask取 0 或 -100),使相邻窗口间能够交换信息——这正是"移位窗口"(SW-MSA)的机制;window_size=7与输入 192x256 的关系:patch 嵌入后第 4 stage 特征为 6x8(192/32 x 256/32),小于窗口尺寸,移位分支会因 pad 后特征尺寸变化而按SwinBlockSequence的逻辑处理(特征不足一个窗口时移位分支退化为普通窗口注意力,这一点可以从源码结构中推断)。
3.3 预训练权重加载与转换
init_weights(约 L659 起)处理了从原始 Swin 仓库加载权重的三类兼容问题,对应配置中的convert_weights=True与init_cfg(type='Pretrained'):
- key 转换:调用 ckpt_convert.py 中的
swin_converter将原始 state_dict 的键名映射到 MMPose 结构; - 绝对位置编码重排:若 state_dict 含
absolute_pos_embed则 reshape/permute 到 (N, C, H, W)(本配置use_abs_pos_embed=False,该分支不会触发); - 相对位置偏置表插值:当预训练表的长度与当前模型不一致时(例如
window_size变化),用双三次插值(F.interpolate(..., mode='bicubic'))将表重采样到当前形状后加载。
加载采用load_state_dict(..., strict=False),因此未覆盖的层(如 head)按init_cfg中 TruncNormal/LayerNorm 常量初始化。
四、训练与测试
4.1 训练
按 train_and_test.md 的方式,单机训练:
# 单卡(8x32 配置在单卡上会自动将 lr 按 auto_scale_lr 缩放到 1/8) python tools/train.py configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_swin-t-p4-w7_8xb32-210e_coco-256x192.py # 8 卡分布式训练 bash ./tools/dist_train.sh configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_swin-t-p4-w7_8xb32-210e_coco-256x192.py 8分布式下可通过CUDA_VISIBLE_DEVICES、PORT指定显卡与通信端口;CPU 训练使用CUDA_VISIBLE_DEVICES=-1。断点续训追加--resume,混合精度训练追加--amp(对 Transformer 模型通常收益有限,配置默认未开)。
4.2 测试
python tools/test.py \ configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_swin-t-p4-w7_8xb32-210e_coco-256x192.py \ <CHECKPOINT_FILE> --out <RESULT_FILE>tools/test.py支持--show-dir可视化预测结果;分布式测试对应tools/dist_test.sh。
4.3 推理
除传统 API 外,仓库提供了基于 Inferencer 的端到端推理入口 demo/inferencer_demo.py 与 demo/image_demo.py,例如:
python demo/inferencer_demo.py tests/data/coco/000000000785.jpg \ --work-dir <OUTPUT_DIR> --show详细参数(含--show-alias等)见 inference.md。
五、引用信息
原模型文档同时给出了各组件的 BibTeX 引用,供论文引用时使用:
- Simple Baselines for Human Pose Estimation and Tracking(Xiao et al., ECCV 2018)
- Swin Transformer: Hierarchical Vision Transformer using Shifted Windows(Liu et al., ICCV 2021)
- Feature Pyramid Networks for Object Detection(Lin et al., CVPR 2017)
- Microsoft COCO: Common Objects in Context(Lin et al., ECCV 2014)
六、关键文件索引
| 内容 | 路径 |
|---|---|
| 本文主体文档(模型成绩表) | swin_coco.md |
| swin-t 256x192 配置 | td-hm_swin-t-p4-w7_8xb32-210e_coco-256x192.py |
| swin-b 256x192 配置 | td-hm_swin-b-p4-w7_8xb32-210e_coco-256x192.py |
| swin-b 384x288 配置 | td-hm_swin-b-p4-w7_8xb32-210e_coco-384x288.py |
| swin-l 256x192 配置 | td-hm_swin-l-p4-w7_8xb32-210e_coco-256x192.py |
| swin-l 384x288 配置 | td-hm_swin-l-p4-w7_8xb32-210e_coco-384x288.py |
| Swin 主干实现 | mmpose/models/backbones/swin.py |
| 预训练权重 key 转换 | mmpose/models/backbones/utils/ckpt_convert.py |
| MSRA 热图编解码 | mmpose/codecs/msra_heatmap.py |
| 默认运行时配置 | configs/base/default_runtime.py |
| 训练/测试指南 | docs/en/user_guides/train_and_test.md |
| 推理指南 | docs/en/user_guides/inference.md |
【免费下载链接】mmposeOpenMMLab Pose Estimation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmpose
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考