MMPose 中基于 ViPNAS 的 COCO-WholeBody 全身姿态估计:配置解析、源码原理与精度实测
2026/9/17 10:25:07 网站建设 项目流程

MMPose 中基于 ViPNAS 的 COCO-WholeBody 全身姿态估计:配置解析、源码原理与精度实测

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

本文围绕 MMPose 在 COCO-WholeBody 数据集上发布的 ViPNAS 系列 top-down 热图方案展开,完整解析td-hm_vipnas-mbv3_8xb64-210e_coco-wholebody-256x192.pytd-hm_vipnas-res50_8xb64-210e_coco-wholebody-256x192.py两份配置的每个字段,并结合mmpose/models/backbones/vipnas_*.pymmpose/models/heads/heatmap_heads/vipnas_head.py源码说明 ViPNAS 经神经架构搜索得到的骨干与"组数可伸缩"反卷积头的工作原理。读完本文,你将掌握在 MMPose 中使用 ViPNAS 训练、评估 133 点全身关键点模型的方法,并理解 top-down 流程中检测框输入、热图编解码、翻转测试等关键环节。

一、背景:ViPNAS 算法与 COCO-WholeBody 数据集

ViPNAS(Efficient Video Pose Estimation via Neural Architecture Search,CVPR 2021)的核心思想是用神经架构搜索(NAS)为姿态估计任务自动搜索网络结构,而非直接复用为图像分类设计的骨干。其搜索空间同时覆盖宽度(width)、深度(depth)、卷积核大小(kernel size)、分组数(groups)与注意力模块(attention)等维度,最终得到的一组高效结构即 MMPose 中的ViPNAS_ResNetViPNAS_MobileNetV3两类骨干。

COCO-WholeBody(Whole-Body Human Pose Estimation in the Wild,ECCV 2020)则是在 COCO 基础上扩展的全身关键点数据集。从 数据集定义 可以看到其关键点编号规则:索引 0–22 为 17 个身体关键点与 6 个脚部关键点,索引 23–90 为 68 个面部关键点(face-0face-67),索引 91–132 为左右手各 21 个手部关键点(每只手hand_root加 5 根手指各 4 点),合计133 个关键点。因此在两个 ViPNAS 配置中,headout_channels=133,即最终卷积层为每个关键点输出一张热图。

二、COCO-WholeBody v1.0 val 上的精度结果

下方结果为 COCO-WholeBody v1.0 验证集上的官方记录,评测时采用在 COCO val2017 上人体 AP 为 56.4 的检测器提供人体框(对应验证配置中的COCO_val2017_detections_AP_H_56_person.json)。指标分别统计 Body、Foot、Face、Hand 与整体 Whole 的 AP/AR:

ArchInput SizeBody APBody ARFoot APFoot ARFace APFace ARHand APHand ARWhole APWhole AR
S-ViPNAS-MobileNetV3256x1920.6190.7000.4770.6080.5850.6890.3860.5050.4730.578
S-ViPNAS-Res50256x1920.6430.7260.5530.6940.5870.6980.4100.5290.4950.607

两份配置的详细元数据(架构、训练数据、各项指标、权重文件)同步维护在 vipnas_coco-wholebody.yml 中,并被 model-index.yml 收录,可直接供 MIM 等工具检索与下载权重。注意同一目录下还提供了 DARK 变体(td-hm_vipnas-mbv3_dark-*td-hm_vipnas-res50_dark-*),对应文档见 vipnas_dark_coco-wholebody.md。

三、配置文件逐段解析

两份配置的骨架完全一致,差异仅在骨干的选择与头部参数。下面以 MobileNetV3 版本为主逐段说明,并在差异处给出 Res50 版本的区别。

3.1 运行时与训练周期

_base_ = ['../../../_base_/default_runtime.py'] train_cfg = dict(max_epochs=210, val_interval=10)
  • 继承仓库通用运行配置 default_runtime.py(含日志、checkpoint、随机种子、环境等默认设置)。
  • 总训练210 个 epoch,每10 个 epoch在验证集上评估一次。

3.2 优化器与学习率调度

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)
  • 优化器为Adam,初始学习率 5e-4(未设置 weight_decay,保持简单基线风格)。
  • 学习率策略分两段:前500 个 iteration做线性 warm-up(初始为 0.001 倍学习率,by_epoch=False表示按 iteration 计数);随后按 epoch 执行 MultiStepLR,在第 170 与第 200 epoch各衰减为原来的 0.1 倍。
  • auto_scale_lr声明基准 batch size 为 512,MMEngine 会根据实际训练 batch size 自动按比例缩放学习率,保证不同显存配置下训练行为一致。

3.3 模型结构:TopdownPoseEstimator + ViPNAS 骨干 + ViPNASHead

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='ViPNAS_MobileNetV3'), head=dict( type='ViPNASHead', in_channels=160, out_channels=133, deconv_out_channels=(160, 160, 160), deconv_num_groups=(160, 160, 160), loss=dict(type='KeypointMSELoss', use_target_weight=True), decoder=codec), test_cfg=dict( flip_test=True, flip_mode='heatmap', shift_heatmap=True, ))

关键点:

  • codec(编解码器):采用MSRAHeatmap,输入图像 256×192(input_size为 (W, H)),输出热图 64×48,高斯核 sigma=2。该 codec 负责训练时把关键点坐标编码为高斯热图、推理时把热图峰值解码回坐标(实现见 msra_heatmap.py)。DARK 变体仅将unbiased=True(见 td-hm_vipnas-mbv3_dark 配置),即解码时使用无偏的 DARK 方法估计亚像素峰值。
  • 数据预处理器PoseDataPreprocessor使用 ImageNet 均值/方差归一化,bgr_to_rgb=True说明输入按 OpenCV 读图约定为 BGR,送入网络前转 RGB。
  • 骨干ViPNAS_MobileNetV3无需额外参数即使用源码内置的 NAS 搜索结构;Res50 版本则为dict(type='ViPNAS_ResNet', depth=50)
  • 头部ViPNASHead输入通道数与骨干末层一致——MobileNetV3 为 160,Res50 为 608。MobileNetV3 版本显式指定了三层反卷积输出通道与分组数均为(160, 160, 160);Res50 版本不写deconv_out_channels,使用头部的默认值(144, 144, 144)(见下文源码说明)。
  • 损失KeypointMSELoss配合use_target_weight=True,对每个关键点按其标注可见性加权计算 MSE,out_channels=133对应 COCO-WholeBody 全部 133 个关键点。
  • 翻转测试flip_test=True时推理会对原图与水平翻转图各前向一次,flip_mode='heatmap'表示在热图层面融合(翻转后的热图按左右对称关键点重排后平均),shift_heatmap=True用于补偿翻转引起的约 1 像素偏移。

3.4 数据加载、流水线与评测

dataset_type = 'CocoWholeBodyDataset' data_mode = 'topdown' data_root = 'data/coco/'
  • 数据集类型CocoWholeBodyDataset,top-down 模式;标注与图像根目录均为data/coco/
  • 训练标注annotations/coco_wholebody_train_v1.0.json,图像前缀train2017/;验证标注annotations/coco_wholebody_val_v1.0.json,图像前缀val2017/
  • 验证/测试框来源bbox_file='data/coco/person_detection_results/COCO_val2017_detections_AP_H_56_person.json',即文档中所说"human AP 为 56.4"的检测器预测结果,用于统一评测协议。
  • 训练流水线LoadImageGetBBoxCenterScale(由检测框计算中心与尺度)→RandomFlip(水平翻转)→RandomHalfBody(随机保留半身关键点区域,增强局部精度)→RandomBBoxTransform(旋转 ±60°,尺度缩放 0.75–1.25)→TopdownAffine(仿射对齐到 256×192)→GenerateTarget(按 codec 生成高斯热图)→PackPoseInputs
  • 验证流水线:仅做对齐,不做增强,保证评测稳定性。
  • DataLoader:训练 batch size 64、2 个 worker;验证 batch size 32。训练侧persistent_workers=True复用 worker 进程减少开销。
  • 评测器CocoWholeBodyMetric加载同一份 val 标注,按 Body/Foot/Face/Hand/Whole 五组分别计算 AP/AR。
  • checkpoint hooksave_best='coco-wholebody/AP',按 Whole AP 保存最优权重。

四、源码级原理:NAS 搜索出的结构与弹性反卷积头

4.1 ViPNAS_ResNet:逐阶段可搜索的宽度/深度/核/分组/注意力

实现位于 vipnas_resnet.py。类ViPNAS_ResNet的构造函数接收一组 NAS 搜索结果参数并设置了默认值:

wid=[48, 80, 160, 304, 608], # 各阶段宽度(stem 起) expan=[None, 1, 1, 1, 1], # 各阶段 expansion dep=[None, 4, 6, 7, 3], # 各阶段 block 数量 ks=[7, 3, 5, 5, 5], # 各阶段卷积核大小 group=[None, 16, 16, 16, 16], # 各阶段分组数 att=[None, True, False, True, True], # 各阶段是否带注意力

从源码结构看,dep[0]被用作 stem 通道数,其余列表元素按dep[1:1+num_stages]驱动 4 个残差阶段:每个阶段使用ViPNAS_Bottleneck,其conv2kernel_sizegroups直接取自搜索结果的ksgroup;当attention=True时,block 末尾会插入ContextBlock做通道上下文注意力(mmcv.cnn.bricks.ContextBlock)。这意味着 ViPNAS 不是简单套用标准 ResNet,而是把"哪个阶段用多大核、多少分组、是否加注意力"都作为可搜索项,最终配置即搜索得到的具体实例。

4.2 ViPNAS_MobileNetV3:轻量级搜索结构

实现位于 vipnas_mbv3.py。类ViPNAS_MobileNetV3同样内嵌搜索默认值:

wid=[16, 16, 24, 40, 80, 112, 160], expan=[None, 1, 5, 4, 5, 5, 6], dep=[None, 1, 4, 4, 4, 4, 4], ks=[3, 3, 7, 7, 5, 7, 5], group=[None, 8, 120, 20, 100, 280, 240], att=[None, True, True, False, True, True, True], stride=[2, 1, 2, 2, 2, 1, 2], act=['HSwish', 'ReLU', 'ReLU', 'ReLU', 'HSwish', 'HSwish', 'HSwish'],

结构上采用 MobileNetV3 风格的倒残差模块(InvertedResidual,见 mmpose/models/backbones/utils):每个 stage 的中间通道为wid * expan;当该 stage 的att为 True 时插入 SE 注意力(HSigmoid门控);激活函数按搜索结果混用 HSwish 与 ReLU。该版本输入 256×192、输出 160 通道特征图,配合头部三层 160 通道反卷积,整体参数量与计算量显著小于 Res50,是文档表中更轻量的选择。

4.3 ViPNASHead:组数可弹性伸缩的反卷积头

头部实现在 vipnas_head.py。类ViPNASHead继承自HeatmapHead,其 docstring 明确指出:与 Simple Baselines 的HeatmapHead不同,ViPNAS 反卷积层的分组数(group numbers)是可伸缩的,因此可以被 NAS 一起搜索优化。默认参数为:

deconv_out_channels=(144, 144, 144), deconv_kernel_sizes=(4, 4, 4), deconv_num_groups=(16, 16, 16),

构造时对三组列表做了长度一致性校验(deconv_out_channelsdeconv_kernel_sizesdeconv_num_groups长度必须一致)。_make_deconv_layers中每个反卷积层的 padding/output_padding 由 kernel size 决定:kernel 4 → padding 1、output_padding 0;kernel 3 → 均为 1;kernel 2 → 均为 0,并强制stride=2bias=False,每个反卷积后接 BatchNorm2d 与 ReLU。两层反卷积之后是final_layer(默认 1×1 卷积)映射到out_channels=133张热图。相比标准HeatmapHead(同见 heatmap_head.py)每组默认分组数为 1 的密集反卷积,ViPNASHead通过deconv_num_groups用分组卷积显著压缩头部计算量——这正是 NAS 在"效率优先"目标下搜索出的设计。

4.4 从配置到前向的整体调用链

  • 训练/测试入口 tools/train.py 与 tools/test.py 读取配置,MMEngine 依据model.type构建TopdownPoseEstimator(mmpose/models/pose_estimators)。
  • 图像经PoseDataPreprocessor归一化后进入骨干(ViPNAS_ResNet/ViPNAS_MobileNetV3),输出低分辨率特征图;
  • ViPNASHead通过分组反卷积逐级上采样(256×192 输入 → 64×48 热图),final_layer输出 133 通道;
  • 训练时KeypointMSELoss对比预测热图与MSRAHeatmap编码的高斯目标;推理时由 codec 的 decode 过程(含翻转测试融合与 DARK 亚像素精修)恢复关键点坐标。

五、训练与评估实战

5.1 单机训练

python tools/train.py configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_vipnas-mbv3_8xb64-210e_coco-wholebody-256x192.py

训练前需按 数据准备指南 将 COCO-WholeBody 标注放置到data/coco/annotations/、图像放置到data/coco/train2017/data/coco/val2017/。多卡分布式训练可改用 tools/dist_train.sh,如:

bash tools/dist_train.sh configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_vipnas-res50_8xb64-210e_coco-wholebody-256x192.py 8

5.2 评估

python tools/test.py configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_vipnas-mbv3_8xb64-210e_coco-wholebody-256x192.py \ /path/to/checkpoints/vipnas_mbv3_coco_wholebody_256x192-xxx.pth

验证阶段依赖data/coco/person_detection_results/COCO_val2017_detections_AP_H_56_person.json提供人体框,评测输出 Body/Foot/Face/Hand/Whole 五组 AP/AR,结果即第三节表格所示协议。预训练权重可从 model zoo(见 vipnas_coco-wholebody.yml 的Weights字段)下载。

5.3 部署到推理

top-down 全身估计通常与检测器串联:先用目标检测(如 demo 目录中的 mmdetection_cfg 提供的人体检测配置)得到人体框,再将框与模型接入 topdown_demo_with_mmdet.py 或 MMPose Inferencer(见 inference 指南)完成端到端推理。

六、调参与扩展建议

  • 算力受限选择 MobileNetV3:当对延迟或显存敏感时,ViPNAS_MobileNetV3在牺牲少量 Whole AP(0.473 vs 0.495)的前提下提供明显更轻的模型;需要更高精度则选ViPNAS_ResNet(Body AP 0.643、Whole AP 0.495)。
  • 追求更高解码精度尝试 DARK:同目录下的 DARK 变体将MSRAHeatmapunbiased=True,在解码阶段采用无偏亚像素估计,通常能带来小幅精度提升,且训练成本几乎不变。
  • 调低输入分辨率:若需进一步加速,可同步修改codec.input_sizecodec.heatmap_size与各 pipeline 的TopdownAffine输入尺寸,并保持热图尺度为输入的 1/4。
  • 更换人体检测器:验证/测试阶段替换bbox_file即可复用于其他检测器协议,例如使用 demo 目录的 RTMDet 人体检测配置生成新的预测框文件。

七、延伸阅读

  • 同目录其他骨干方案对比:HRNet(hrnet_coco-wholebody.md)、ResNet 系列(resnet_coco-wholebody.md)。
  • 全身姿态估计的更多方法与部署示例见 wholebody_2d_keypoint 总览 与 2D 全身 Demo。
  • 编解码器机制详解见 codecs 指南,配置文件书写规范见 configs 指南。

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

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

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

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

立即咨询