MMPose 中的 CPM 卷积姿态机:COCO 自上而下热图模型配置、训练与实现原理全解析
MMPose 中的 CPM 卷积姿态机COCO 自上而下热图模型配置、训练与实现原理全解析【免费下载链接】mmposeOpenMMLab Pose Estimation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmpose导读本文围绕 MMPose 仓库中 CPMConvolutional Pose Machines卷积姿态机在 COCO 人体关键点数据集上的自上而下Top-Down热图配置展开完整介绍configs/body_2d_keypoint/topdown_heatmap/coco/cpm_coco.md收录的两套官方训练配置、其 COCO val2017 上的评估结果以及CPM骨干网络与CPMHead多阶段热图头的源码级实现原理。读完本文你将掌握如何在 MMPose 中复现 CPM 的 COCO 训练、读懂其每层网络结构、理解多阶段中间监督与 MSRA 热图编解码机制并学会独立修改配置以获得不同输入分辨率下的行为。一、CPM 配置文档速览官方成果表与引用信息1.1 算法与数据集出处configs/body_2d_keypoint/topdown_heatmap/coco/cpm_coco.md在头部以details折叠块的形式引用了两个文献算法CPM 论文 Convolutional Pose MachinesWei, Shih-En 等人发表于 CVPR 2016数据集COCO Microsoft COCO: Common Objects in ContextLin 等人发表于 ECCV 2014。两个条目都附带了可直接复制的 BibTeX 引用方便你在论文中正确引用该模型与数据来源。该 md 文件同时是 模型索引 的元数据来源后者登记了两套配置的 Architecture、Training Data、Task、各项指标与权重下载地址。1.2 COCO val2017 官方评测结果文档记录了在检测器人体 AP 为 56.4的前提下即使用COCO_val2017_detections_AP_H_56_person.json提供的检测框CPM 在 COCO val2017 上的评估指标两套配置分别对应 256×192 与 384×288 两种输入尺寸ArchInput SizeAPAP^50AP^75ARAR^50ckptlogcpm256x1920.6270.8620.7090.6890.906ckptlogcpm384x2880.6520.8650.7300.7100.907ckptlog对比可见输入分辨率从 256×192 提升到 384×288 后AP 由 0.627 提升至 0.6522.5 AP但训练批次从 8×64 调整为 8×32以换取更大的显存开销。这也是选择配置时最核心的权衡点分辨率越高精度越好但显存与训练成本也越高。二、配置文件逐段解析td-hm_cpm_8xb64-210e_coco-256x192.pyCPM 在 COCO 上的训练配置位于configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_cpm_8xb64-210e_coco-256x192.py另一套 384×288 配置为configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_cpm_8xb32-210e_coco-384x288.py两者除分辨率、批大小与sigma外完全一致。下面以 256×192 版本为线索逐段拆解。2.1 基础运行时与训练总览_base_ [../../../_base_/default_runtime.py] # runtime train_cfg dict(max_epochs210, val_interval10)继承自 configs/base/default_runtime.py其中包含了默认钩子LoggerHook、CheckpointHook 每 10 个 epoch 保存一次、PoseVisualizationHook 默认关闭、BadCaseAnalysisHook 默认关闭、SyncBuffersHook、本地可视化后端LocalVisBackend、env_cfgmp_start_methodfork等公共运行时配置。训练总时长210 个 epoch每 10 个 epoch 做一次验证。2.2 优化器与学习率调度# optimizer optim_wrapper dict(optimizerdict( typeAdam, lr5e-4, )) # learning policy param_scheduler [ dict( typeLinearLR, begin0, end500, start_factor0.001, by_epochFalse), # warm-up dict( typeMultiStepLR, begin0, end210, milestones[170, 200], gamma0.1, by_epochTrue) ] # automatically scaling LR based on the actual training batch size auto_scale_lr dict(base_batch_size512)使用Adam 优化器初始学习率5e-4。学习率策略分为两段前500 个 iteration使用LinearLR做 warm-up起始学习率为 0.001 倍之后切换为MultiStepLR在第 170 与 200 个 epoch处各衰减 0.1 倍。auto_scale_lr dict(base_batch_size512)表示基准批大小为 512实际训练时若批大小与 512 不同MMEngine 会自动按比例缩放学习率便于在单卡/多卡环境下复现官方指标。2.3 关键点编解码器MSRAHeatmap# codec settings codec dict( typeMSRAHeatmap, input_size(192, 256), heatmap_size(24, 32), sigma2)CPM 配置采用MSRA 高斯热图编解码器其实现位于 mmpose/codecs/msra_heatmap.pyinput_size(192, 256)模型输入图像尺寸宽 192高 256heatmap_size(24, 32)输出热图尺寸为输入的 1/8sigma2高斯核标准差。在编码阶段encodeMSRAHeatmap将关键点坐标除以scale_factor输入尺寸与热图尺寸之比后通过generate_gaussian_heatmaps生成 (K, H, W) 的高斯热图与 (N, K) 的 keypoint_weights源码在解码阶段decode则对热图取最大值位置再经refine_keypoints一阶梯度精修得到亚像素坐标最后乘以scale_factor还原到输入图像空间源码。细节当unbiasedTrue时该编解码器会走 DarkPose 的generate_unbiased_gaussian_heatmaps与refine_keypoints_dark分支CPM 的官方配置未开启该选项保持unbiasedFalse的经典 MSRA 方式。2.4 模型组装TopdownPoseEstimator CPM CPMHead# model settings model dict( typeTopdownPoseEstimator, data_preprocessordict( typePoseDataPreprocessor, mean[123.675, 116.28, 103.53], std[58.395, 57.12, 57.375], bgr_to_rgbTrue), backbonedict( typeCPM, in_channels3, out_channels17, feat_channels128, num_stages6), headdict( typeCPMHead, in_channels17, out_channels17, num_stages6, deconv_out_channelsNone, final_layerNone, lossdict(typeKeypointMSELoss, use_target_weightTrue), decodercodec), test_cfgdict( flip_testTrue, flip_modeheatmap, shift_heatmapTrue, ))关键字段说明TopdownPoseEstimator自上而下姿态估计器先由检测器给出人体框再对每个框内的人体做关键点回归PoseDataPreprocessorImageNet 均值和标准差归一化bgr_to_rgbTrue表示输入图像按 BGR 读取、送入网络前转换为 RGBbackboneCPM输入 3 通道、输出 17 通道COCO 17 个关键点、特征通道 128、共6 个 stageheadCPMHeadin_channels17、out_channels17、num_stages6deconv_out_channelsNone与final_layerNone表示不额外添加反卷积上采样层与最后的 1×1 卷积层因为 CPM 骨干自身已直接输出热图每个 stage 均使用KeypointMSELoss(use_target_weightTrue)计算损失decoder直接复用上文的codectest_cfg开启flip test水平翻转测试增强flip_modeheatmap表示对热图做翻转融合shift_heatmapTrue表示翻转后按关键点对称索引进行偏移校正实现见 CPMHead.predict。2.5 数据流水线pipeline# pipelines train_pipeline [ dict(typeLoadImage), dict(typeGetBBoxCenterScale), dict(typeRandomFlip, directionhorizontal), dict(typeRandomHalfBody), dict(typeRandomBBoxTransform), dict(typeTopdownAffine, input_sizecodec[input_size]), dict(typeGenerateTarget, encodercodec), dict(typePackPoseInputs) ] val_pipeline [ dict(typeLoadImage), dict(typeGetBBoxCenterScale), dict(typeTopdownAffine, input_sizecodec[input_size]), dict(typePackPoseInputs) ]训练流水线在LoadImage与GetBBoxCenterScale之后依次应用水平RandomFlip、RandomHalfBody有概率只保留一半身体的关键点增强局部遮挡鲁棒性、RandomBBoxTransform对检测框做随机缩放/平移/旋转、TopdownAffine按输入尺寸做仿射变换、GenerateTarget用codec生成热图标签、PackPoseInputs打包为模型输入。验证流水线不含任何随机增强且GenerateTarget由PackPoseInputs取代——标签只在训练时需要。2.6 数据加载器与评测器train_dataloader dict( batch_size64, num_workers2, persistent_workersTrue, samplerdict(typeDefaultSampler, shuffleTrue), datasetdict( typedataset_type, data_rootdata_root, data_modedata_mode, ann_fileannotations/person_keypoints_train2017.json, data_prefixdict(imgtrain2017/), pipelinetrain_pipeline, )) val_dataloader dict( batch_size32, num_workers2, persistent_workersTrue, drop_lastFalse, samplerdict(typeDefaultSampler, shuffleFalse, round_upFalse), datasetdict( typedataset_type, data_rootdata_root, data_modedata_mode, ann_fileannotations/person_keypoints_val2017.json, bbox_filedata/coco/person_detection_results/ COCO_val2017_detections_AP_H_56_person.json, data_prefixdict(imgval2017/), test_modeTrue, pipelineval_pipeline, )) test_dataloader val_dataloader val_evaluator dict( typeCocoMetric, ann_filedata_root annotations/person_keypoints_val2017.json) test_evaluator val_evaluator数据根目录为data/coco/使用CocoDataset、data_modetopdown训练集批大小 648 卡即 8×64验证集批大小 32验证/测试使用COCO_val2017_detections_AP_H_56_person.json作为人体检测框来源——这正是文档中检测器人体 AP 为 56.4那句说明的出处指标由CocoMetric计算输出 COCO 的 AP/AR 系列指标配置文件顶部还设置了default_hooks dict(checkpointdict(save_bestcoco/AP, rulegreater))即以验证集 AP 为准保存最优权重。三、源码级原理CPM 骨干网络的 6 阶段结构CPM骨干网络实现在 mmpose/models/backbones/cpm.py由三部分组成3.1 Stem第一阶段网络self.stem nn.Sequential( ConvModule(in_channels, 128, 9, padding4, norm_cfgnorm_cfg), nn.MaxPool2d(kernel_size3, stride2, padding1), ConvModule(128, 128, 9, padding4, norm_cfgnorm_cfg), nn.MaxPool2d(kernel_size3, stride2, padding1), ConvModule(128, 128, 9, padding4, norm_cfgnorm_cfg), nn.MaxPool2d(kernel_size3, stride2, padding1), ConvModule(128, 32, 5, padding2, norm_cfgnorm_cfg), ConvModule(32, 512, 9, padding4, norm_cfgnorm_cfg), ConvModule(512, 512, 1, padding0, norm_cfgnorm_cfg), ConvModule(512, out_channels, 1, padding0, act_cfgNone))以 9×9/5×5/1×1 卷积配合三次 3×3 stride2 的 MaxPooling 下采样最终在stem末尾直接输出第一个 stage 的 17 通道热图act_cfgNone表示最后一层无激活网络结构与论文一致初始阶段即可给出一个粗糙的关键点预测。3.2 Middle 分支中继特征提取self.middle nn.Sequential( ConvModule(in_channels, 128, 9, padding4, norm_cfgnorm_cfg), nn.MaxPool2d(kernel_size3, stride2, padding1), ConvModule(128, 128, 9, padding4, norm_cfgnorm_cfg), nn.MaxPool2d(kernel_size3, stride2, padding1), ConvModule(128, 128, 9, padding4, norm_cfgnorm_cfg), nn.MaxPool2d(kernel_size3, stride2, padding1))middle分支从原始输入单独提取与stem同空间分辨率的特征同样三次下采样用于在后续 stage 中与前一 stage 的热图拼接为网络补充原始图像信息。3.3 多阶段循环Stage 2 ~ 6self.cpm_stages nn.ModuleList([ CpmBlock( middle_channels out_channels, channels[feat_channels, feat_channels, feat_channels], kernels[11, 11, 11], norm_cfgnorm_cfg) for _ in range(num_stages - 1) ]) self.middle_conv nn.ModuleList([ nn.Sequential(ConvModule(128, middle_channels, 5, padding2, norm_cfgnorm_cfg)) for _ in range(num_stages - 1) ]) self.out_convs nn.ModuleList([ nn.Sequential( ConvModule(feat_channels, feat_channels, 1, padding0, norm_cfgnorm_cfg), ConvModule(feat_channels, out_channels, 1, act_cfgNone)) for _ in range(num_stages - 1) ])forward中每个 stage 的执行逻辑为源码inp_feat torch.cat([out_feats[-1], self.middle_convind], 1) cpm_feat single_stage(inp_feat) out_feat out_conv(cpm_feat) out_feats.append(out_feat)即把上一个 stage 的输出热图与降维后的middle特征拼接维度为middle_channels out_channels经CpmBlock3 层 11×11 卷积源码与out_convs1×1 卷积输出新的 17 通道热图。每个 stage 的输入都显式包含上一阶段的热图这正是姿态机Pose Machine通过结构化上下文逐步精修预测的核心思想也是它对相邻关键点空间关系建模的基础。最终forward返回一个包含6 张热图的列表shape 均为 (1, 17, H/8, W/8)每个 stage 一张全部送入CPMHead参与损失计算。四、源码级原理CPMHead 的多阶段中间监督CPMHead实现在 mmpose/models/heads/heatmap_heads/cpm_head.py它接收骨干网络输出的多张 stage 热图并完成两件事训练时的多阶段损失计算与测试时的关键点解码。4.1 前向与测试时的翻转增强forward断言特征数量等于num_stages并对每个 stage 依次施加可选的反卷积层与最终卷积层本配置两者均为None退化为恒等映射直接透传骨干输出。测试阶段predict的核心逻辑为开启flip_test时将原图与水平翻转图的热图按flip_indices对称翻转后取平均shift_heatmapTrue校正偏移只取最后一个 stage的热图multi_stage_heatmaps[-1]进行decode早期 stage 只参与训练监督不参与最终预测若output_heatmapsTrue还会以PixelData形式返回热图。4.2 多阶段损失叠加loss方法对每个 stage 的热图分别与同一个 GT 热图计算KeypointMSELoss并累加源码for i in range(self.num_stages): loss_i loss_func(multi_stage_pred_heatmaps[i], gt_heatmaps, keypoint_weights) if loss_kpt not in losses: losses[loss_kpt] loss_i else: losses[loss_kpt] loss_i这种多阶段中间监督Intermediate Supervision是 CPM 的训练关键即使前几个 stage 预测不够准其热图也会被强制对齐到 GT避免深层网络梯度消失并加速收敛每个 stage 可共享同一个损失模块默认也可通过传入长度等于num_stages的loss列表为不同 stage 配置不同损失源码中显式校验了长度一致性损失函数为 KeypointMSELossuse_target_weightTrue表示不同关键点按其可见性权重加权遮挡/未标注关键点的梯度贡献被压低损失之外loss方法还会基于最后一个 stage 的热图与 GT 计算pose_pck_accuracy作为训练中的acc_pose指标。4.3 关于 deconv 与 final_layer 的灵活设计CPMHead的构造函数支持deconv_out_channels为None时各 stage 使用nn.Identity()不做反卷积上采样本配置即如此因为 CPM 骨干的输出分辨率已是 1/8 且空间信息足够传元组如(32, 32)时则为每个 stage 构建kernel4/3/2、stride2 的反卷积栈源码支持 kernel 4→padding 1、kernel 3→output_padding 1、kernel 2→padding 0 三种映射final_layer为None时同样退化为恒等为 dict如dict(kernel_size1)时构建 1×1 卷积映射到out_channels。单元测试 tests/test_models/test_heads/test_heatmap_heads/test_cpm_head.py 分别验证了 w/o deconv、w/ deconv、w/o final layer、w/ decoder 及多 stage 损失叠加等分支可作为理解这些选项行为的最小示例。五、COCO 数据准备与训练、测试实战5.1 数据准备训练需要按 COCO 官方目录结构放置数据data/coco/ ├── annotations/ │ ├── person_keypoints_train2017.json │ └── person_keypoints_val2017.json ├── train2017/ ├── val2017/ └── person_detection_results/ └── COCO_val2017_detections_AP_H_56_person.json关键点标注来自annotations/图像来自train2017/与val2017/验证/测试必需的人体检测框结果文件COCO_val2017_detections_AP_H_56_person.json对应文档中detector having human AP of 56.4需要按 数据准备指南中文见 docs/zh_cn/user_guides/prepare_datasets.md预先准备。5.2 训练单机多卡训练使用 tools/dist_train.shbash tools/dist_train.sh configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_cpm_8xb64-210e_coco-256x192.py 8如需 384×288 配置将配置路径替换为configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_cpm_8xb32-210e_coco-384x288.py。单卡可用 tools/train.py以 Slurm 集群运行时则用 tools/slurm_train.sh。训练时auto_scale_lr会按实际批大小相对 512 自动缩放学习率因此单卡batch64训练时学习率会被相应调小。5.3 测试与指标复现bash tools/dist_test.sh configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_cpm_8xb64-210e_coco-256x192.py \ work_dirs/td-hm_cpm_8xb64-210e_coco-256x192/best_coco_AP_epoch_210.pth 8测试默认在 COCO val2017 上计算CocoMetric的 AP/AR 指标由于配置了save_bestcoco/AP训练后最优权重会以best_coco_AP_epoch_*.pth形式保存在 work_dirs 下用它进行测试即可复现文档表格中的指标。5.4 推理与部署下载文档表格中提供的 ckpt 后可使用 demo/inferencer_demo.py 快速推理python demo/inferencer_demo.py tests/data/coco/000000000785.jpg \ td-hm_cpm_8xb64-210e_coco-256x192 \ --draw-heatmap --pred-out-dir vis_results其中td-hm_cpm_8xb64-210e_coco-256x192是 模型索引 中登记的模型名推理器会自动解析配置并加载对应权重--draw-heatmap可同时可视化最后 stage 的热图。端到端的人体检测关键点流程可参考 demo/docs/en/2d_human_pose_demo.md。六、两种分辨率配置对比与调参建议配置输入尺寸批大小sigmaAPAP^50AP^75td-hm_cpm_8xb64-210e_coco-256x192.py256×1926420.6270.8620.709td-hm_cpm_8xb32-210e_coco-384x288.py384×2883230.6520.8650.730值得注意的是两套配置中sigma并非不变256×192 对应sigma2384×288 对应sigma3。这是因为高斯核的绝对尺寸应随热图分辨率24×32 vs 36×48等比放大编码器在 mmpose/codecs/msra_heatmap.py 中按scale_factor input_size / heatmap_size缩放坐标而 sigma 需要手工按分辨率匹配。修改输入分辨率时应遵循以下经验input_size与heatmap_size保持 8:1 的比例如 256×192→32×24384×288→48×36按分辨率增大适度调大sigma官方 256×192→2、384×288→3 即为基准分辨率提升后显存需求显著上升需按显存余量下调 batch size 或卡数保持flip_test、shift_heatmap、RandomHalfBody等数据与推理策略不变可稳定获得与官方一致的精度收益。七、从源码结构看 CPM 与同类算法的定位从仓库结构看CPM 属于 configs/body_2d_keypoint/topdown_heatmap/coco 目录下自上而下热图法家族的一员与 Hourglass、HRNet、MSPN 等并列。它的特点可以概括为多阶段串行精修6 个 stage 逐级细化热图每一级都显式拼接上一级预测梯度由中间监督直达浅层backbone无需反卷积上采样骨干末尾直接输出 1/8 分辨率热图CPMHead在本配置中保持恒等映射整体结构简洁、参数量少轻量实用以 256×192 输入即取得 COCO val2017 AP 0.627 的可用精度适合作为基线模型验证数据增强、损失设计等改进手段仓库内 hrnet_augmentation_coco、resnet_dark_coco 等即展示了同框架下其他算法的同类实验。如需在生产环境中追求更高精度可横向对比仓库内 HRNethrnet_coco、Lite-HRNet、ViTPose 等方案如需在边缘设备部署可参考 部署指南中文见 docs/zh_cn/user_guides/how_to_deploy.md对 CPM 这类轻量模型做转换加速。结语本文完整还原了 configs/body_2d_keypoint/topdown_heatmap/coco/cpm_coco.md 中 CPM 在 COCO 上的官方成果并从配置、骨干网络、多阶段头、编解码器、训练测试全链路给出源码级解析。CPM 虽然诞生于 2016 年但其多阶段姿态机思想在 MMPose 的现代工程化实现中依旧清晰可读是理解自上而下热图法、中间监督训练与翻转测试增强的上手模型。基于上述配置与源码路径你可以直接复现官方指标并在此基础上进一步扩展实验。【免费下载链接】mmposeOpenMMLab Pose Estimation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmpose创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考