MMPose 中的 ED-Pose基于显式框检测的端到端多人姿态估计COCO 模型配置与源码解析【免费下载链接】mmposeOpenMMLab Pose Estimation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmpose本文以 MMPose 仓库中的 ED-Pose 模型卡片configs/body_2d_keypoint/edpose/coco/edpose_coco.md为核心系统讲解 ED-PoseICLR2023在 COCO 数据集上的模型配置、结果复现方式与底层实现原理。读完本文你将掌握该模型配置文件的每一个关键参数、EDPoseHead与EDPoseLabel的源码级工作机制以及如何使用仓库提供的预训练权重进行推理与评测。ED-Pose 算法背景显式框检测统一端到端多人姿态估计ED-PoseExplicit Box Detection Unifies End-to-End Multi-Person Pose Estimation论文发表于 ICLR 2023是一种端到端的 bottom-up 多人姿态估计方法。与传统的 top-down 两阶段方法先检测人框、再对每个人做关键点估计不同ED-Pose 将人体框检测与关键点估计统一在同一个基于 Transformer 的端到端框架内完成避免了级联误差也省去了 NMS 等后处理。模型卡片中给出了官方 BibTeX 引用信息configs/body_2d_keypoint/edpose/coco/edpose_coco.mdinproceedings{ yang2023explicit, title{Explicit Box Detection Unifies End-to-End Multi-Person Pose Estimation}, author{Jie Yang and Ailing Zeng and Shilong Liu and Feng Li and Ruimao Zhang and Lei Zhang}, booktitle{International Conference on Learning Representations}, year{2023}, url{https://openreview.net/forum?ids4WVupnJjmX} }同时模型卡片也分别引用了其骨干网络 ResNetCVPR2016与训练/评测数据集 COCOECCV2014两篇文献表明该模型在 MMPose 中的实现由ED-Pose 检测头 ResNet 骨干 COCO 数据集三部分构成。在 MMPose 的组件生态中ED-Pose 归属于 bottom-up 流水线整个模型由BottomupPoseEstimatormmpose/models/pose_estimators/bottomup.py承载数据模式为data_mode bottomup与 heatmap 类的 bottom-up 方法共享同一套 estimator 基类但预测头是完全不同的 Transformer 结构。COCO 模型结果模型库一览模型卡片在 Results on COCO val2017 一节给出了当前仓库唯一一个 ED-Pose 模型的结果该表同时被收录进 configs/body_2d_keypoint/edpose/coco/edpose_coco.yml 的模型索引中ArchBackBoneAPAP50AP75ARAR50ckptlogedpose_res50_cocoResNet-500.7160.8970.7830.7930.943ckptlog其中 AP 为 COCO 标准评测指标AP0.5/AP0.75为不同 IoU 阈值下的精度AR 为平均召回率。该权重.pth是从 ED-Pose 官方仓库转换而来模型卡片明确标注 The checkpoint is converted from the official repo对应训练配置中的3rdparty命名即指第三方官方仓库转换权重。需要特别留意两个关键限制模型卡片原话训练暂不支持The training of EDPose is not supported yet. It will be supported in the future updates.——即当前 MMPose 中只能使用该权重做推理与评测不能直接训练。配置格式要求The above config follows Pure Python style. Please installmmengine0.8.2to use this config.——该配置是纯 Python 风格配置_base_通过read_base导入需要mmengine0.8.2才能正确解析。这两个限制在源码中也有对应证据EDPoseHead.loss()直接抛出了NotImplementedError(the training of EDPose has not been supported. Please stay tuned for further update.)见 mmpose/models/heads/transformer_heads/edpose_head.py。配置详解纯 Python 风格的 ED-Pose COCO 配置配置文件 configs/body_2d_keypoint/edpose/coco/edpose_res50_8xb2-50e_coco-800x1333.py 由文件名即可读出关键信息ResNet-50 骨干、8 卡 × batch size 2、50 个 epoch、输入分辨率 800×1333。下面按模块逐层拆解。基类继承与运行时配置配置开头通过read_base继承自 configs/base/default_runtime.py并覆写训练超参from mmengine.config import read_base with read_base(): from mmpose.configs._base_.default_runtime import * # noqa # runtime train_cfg.update(max_epochs50, val_interval10) # noqamax_epochs50表示训练 50 个 epochval_interval10表示每 10 个 epoch 验证一次。此外还更新了 checkpoint hook按 COCO 的AP指标保存最优权重default_hooks.update( # noqa checkpointdict(save_bestcoco/AP, rulegreater))优化器与学习率策略# optimizer optim_wrapper dict(optimizerdict( typeAdam, lr1e-3, )) # learning policy param_scheduler [ dict(typeLinearLR, begin0, end500, start_factor0.001, by_epochFalse), # warm-up dict( typeMultiStepLR, begin0, end140, milestones[33, 45], gamma0.1, by_epochTrue) ] # automatically scaling LR based on the actual training batch size auto_scale_lr dict(base_batch_size80)优化器为 Adam初始学习率1e-3前 500 个 iteration 做线性 warm-up起始因子 0.001之后按 MultiStepLR 在 milestone 33、45 处将学习率衰减为原来的 0.1auto_scale_lr声明了基准 batch size 为 80训练时若实际 batch size 不同MMPose/MMEngine 会自动按比例缩放学习率配合--auto-scale-lr使用。标签编解码器 EDPoseLabel# codec settings codec dict(typeEDPoseLabel, num_select50, num_keypoints17)这是 ED-Pose 专用的标签编解码器配置num_select50表示推理时从预测结果中按分数挑选前 50 个候选实例num_keypoints17对应 COCO 人体 17 个关键点。该 codec 在 mmpose/codecs/edpose_label.py 中实现稍后会在源码解析一节详细展开。模型结构BottomupPoseEstimator ResNet-50 EDPoseHeadmodel dict( typeBottomupPoseEstimator, data_preprocessordict( typePoseDataPreprocessor, mean[123.675, 116.28, 103.53], std[58.395, 57.12, 57.375], bgr_to_rgbTrue, pad_size_divisor1), backbonedict( typeResNet, depth50, num_stages4, out_indices(1, 2, 3), frozen_stages1, norm_cfgdict(typeFrozenBatchNorm2d, requires_gradFalse), norm_evalTrue, stylepytorch, init_cfgdict( typePretrainedInit, checkpointtorchvision://resnet50)), neckdict( typeChannelMapper, in_channels[512, 1024, 2048], kernel_size1, out_channels256, act_cfgNone, norm_cfgdict(typeGroupNorm, num_groups32), num_outs4), ...模型各部分说明data_preprocessor使用 ImageNet 风格的归一化均值/方差输入需从 BGR 转为 RGBbackboneResNet-50输出第 2/3/4 个 stage 的特征out_indices(1, 2, 3)通道数 512/1024/2048第 1 个 stage 冻结frozen_stages1归一化层使用FrozenBatchNorm2d来自mmpose.models.utils即冻结的 BN不再更新统计量权重从 torchvision 的 resnet50 预训练初始化neckChannelMapper将 512/1024/2048 三个通道统一映射到 256 维并在头部拼接出第 4 个下采样层num_outs4从而构成 Transformer 编码器所需的 4 层多尺度特征金字塔归一化使用 GroupNorm32 组不使用激活函数。EDPoseHead 与 Transformer 配置配置中最核心的部分是headtypeEDPoseHead其关键参数如下headdict( typeEDPoseHead, num_queries900, num_feature_levels4, num_keypoints17, as_two_stageTrue, encoderdict( num_layers6, layer_cfgdict( # DeformableDetrTransformerEncoderLayer self_attn_cfgdict( # MultiScaleDeformableAttention embed_dims256, num_heads8, num_levels4, num_points4, batch_firstTrue), ffn_cfgdict( embed_dims256, feedforward_channels2048, num_fcs2, ffn_drop0.0))), decoderdict( num_layers6, embed_dims256, layer_cfgdict( # DeformableDetrTransformerDecoderLayer self_attn_cfgdict( # MultiheadAttention embed_dims256, num_heads8, batch_firstTrue), cross_attn_cfgdict( # MultiScaleDeformableAttention embed_dims256, batch_firstTrue), ffn_cfgdict( embed_dims256, feedforward_channels2048, ffn_drop0.1)), query_dim4, num_feature_levels4, num_group100, num_dn100, num_box_decoder_layers2, return_intermediateTrue), out_headdict(num_classes2), positional_encodingdict( num_pos_feats128, temperatureH20, temperatureW20, normalizeTrue), denosing_cfgdict( dn_box_noise_scale0.4, dn_label_noise_ratio0.5, dn_labelbook_size100, dn_attn_mask_type_list[match2dn, dn2dn, group2group]), data_decodercodec), test_cfgdict(Pmultiscale_testFalse, flip_testFalse, num_select50), train_cfgdict())各参数的含义与影响参数取值说明num_queries900Transformer 解码器的初始查询数量num_feature_levels4使用 4 层多尺度特征由 ChannelMapper 输出as_two_stageTrue采用 two-stage 方式从编码器输出中挑选 top-k 作为解码器初始框提案encoder.num_layers6编码器 6 层 Deformable DETR 编码层自注意力为多尺度可变形注意力num_heads8, num_levels4, num_points4decoder.num_layers6解码器 6 层自注意力用普通 MultiheadAttention交叉注意力用多尺度可变形注意力decoder.query_dim4参考点/查询表示为(cx, cy, w, h)四维decoder.num_group100每组 1 个人体框 17 个关键点共 100 组即解码 100 个人的 1800 个 tokendecoder.num_dn100去噪训练DN查询数量训练时使用推理时为 0decoder.num_box_decoder_layers2前 2 层解码层只更新人体框之后进行查询展开到关键点out_head.num_classes2人体检测的分类数person 1 类 背景 1 类denosing_cfg—去噪训练超参框噪声尺度 0.4、标签噪声比例 0.5、标签簿大小 100、三组注意力掩码test_cfg—flip_testFalseED-Pose 不支持翻转测试、num_select50Pmultiscale_testFalse表示不做多尺度测试。数据流水线与 dataloader训练流水线对输入做了较复杂的增广配置第 146-181 行train_pipeline [ dict(typeLoadImage), dict(typeRandomFlip, directionhorizontal), dict( typeRandomChoice, transforms[ [ # 分支一直接随机尺度缩放 dict( typeRandomChoiceResize, scales[(480, 1333), (512, 1333), (544, 1333), (576, 1333), (608, 1333), (640, 1333), (672, 1333), (704, 1333), (736, 1333), (768, 1333), (800, 1333)], keep_ratioTrue) ], [ # 分支二先放大到长边 4200再随机裁剪再缩放回目标尺度 dict( typeBottomupRandomChoiceResize, scales[(400, 4200), (500, 4200), (600, 4200)], keep_ratioTrue), dict( typeBottomupRandomCrop, crop_typeabsolute_range, crop_size(384, 600), allow_negative_cropTrue), dict( typeBottomupRandomChoiceResize, scales[(480, 1333), (512, 1333), (544, 1333), (576, 1333), (608, 1333), (640, 1333), (672, 1333), (704, 1333), (736, 1333), (768, 1333), (800, 1333)], keep_ratioTrue) ] ]), dict(typePackPoseInputs), ]其中分支二注释明确说明 The radio of all image in train dataset 7, follow the original implement即该放大-裁剪-再缩放策略是为了与官方实现保持一致COCO 训练集所有图像宽高比均小于 7。allow_negative_cropTrue允许裁剪出不含任何标注实例的区域属于随机裁剪的对抗增广。验证流水线将图像缩放到(800, 1333)并保持宽高比同时用PackPoseInputs打包了crowd_index、input_center、input_scale、flip_indices、skeleton_links等 bottom-up 评测所需的 meta 信息。dataloader 部分训练batch_size1、num_workers1、samplerDefaultSampler(shuffleFalse)验证/测试batch_size1、num_workers8、drop_lastFalse。注意文件名中的8xb2是指 8 卡 × 每卡 batch 2而这里单卡配置batch_size1是分布式训练下的单卡视角。评测器为CocoMetric且显式设置了nms_modenone、score_modekeypoint——ED-Pose 是端到端方法无需传统 heatmap 方法的 NMS 后处理。源码解析EDPoseHead 的内部结构与关键机制ED-Pose 的核心实现在 mmpose/models/heads/transformer_heads/edpose_head.py从官方仓库 IDEA-Research/ED-Pose 改编许可协议为 IDEA License 1.0。整个 head 由三部分构成对应EDPoseHead.__init__第 594 行起EDPoseDecoder第 30 行起ED-Pose 特有的 Transformer 解码器EDPoseOutHead第 343 行起最终预测头输出分类 logits、人体框与关键点EDPoseHead第 594 行起继承自TransformerHead负责串联编码器、解码器与预测头。查询展开Query Expansion从人框到关键点EDPoseDecoder是理解 ED-Pose 的关键。解码器共 6 层配置中num_box_decoder_layers2其工作流程见 edpose_head.py 第 146-284 行前 2 层人体检测阶段解码器仅处理num_group × 1个人体框查询通过bbox_embed迭代回归人体框(cx, cy, w, h)的偏移查询展开query expansion在第 2 层结束后用分类头对当前人框查询打分选取 top-100 高分查询为每个选中的人体框复制生成 17 个关键点查询通过self.keypoint_embed可学习嵌入加到人框查询上同时为每个关键点初始化一个hw嵌入nn.Embedding(num_keypoints, 2)第 96 行刻画其相对人体框的宽高比例后 4 层人-关键点联合阶段查询数量从 100 扩增到100 × (1 17) 1800交替更新人体框取每组索引0::18的 token与 17 个关键点坐标。EDPoseOutHead中对应的预测分支在 edpose_head.py 第 465-579 行前 2 层只输出pred_boxes与pred_class之后每层额外输出pred_keypoints关键点表示为一个(bs, num_group, 17, 3)的(x, y, v)张量再展平为(bs, num_group, 51)并重组为(x1,y1,x2,y2,...,v1,v2,...)布局keypoint_xyzxyz_to_xyxyzz第 581 行。去噪训练Denoising与注意力掩码prepare_for_denosingedpose_head.py 第 1150 行起实现了 DAB-DETR 风格的训练期去噪策略将每张图的 GT 框/标签/关键点复制扩充到refine_queries_num100份随机重采样以匹配数量按dn_box_noise_scale0.4对人框施加噪声、按dn_label_noise_ratio0.5随机替换标签从大小为dn_labelbook_size100的标签簿中采样构造三组注意力掩码match2dn、dn2dn、group2group用于隔离真实查询与去噪查询之间的信息泄漏推理时self.trainingFalse去噪查询数为 0注意力掩码退化为只保证同一组内人框与自身关键点可以互相注意、不同组之间相互屏蔽的稀疏掩码结构第 1150-1178 行。此外two_stage机制通过gen_encoder_output_proposals第 1079 行从编码器输出中为每个特征位置生成初始提案再用torch.topk选出 top-900 作为解码器初始参考点与查询pre_decoder第 870-945 行。推理路径与限制EDPoseHead.predictedpose_head.py 第 1013-1034 行中有一个值得注意的硬约束当test_cfg[flip_test]True时会直接抛出NotImplementedError(flip_test is currently not supported for EDPose. Please set model.test_cfg.flip_testFalse)。因此配置中显式写明了flip_testFalse做任何修改都可能导致推理报错。同时EDPoseHead.loss第 1338 行抛出NotImplementedError再次印证模型卡片中训练暂不支持的说明。这决定了当前 ED-Pose 在 MMPose 中的正确打开方式是加载转换权重做评测与推理而不是重新训练。源码解析EDPoseLabel 标签编解码器mmpose/codecs/edpose_label.py 中的EDPoseLabel继承自BaseKeypointCodec承担两个职责编码encode第 50-104 行将图像空间中的标注归一化到[0,1]bbox 先由(x1,y1,x2,y2)转为(cx,cy,w,h)bbox_xyxy2cs再除以[w,h,w,h]关键点坐标除以[w, h]面积除以w * h。解码decode第 106-153 行从归一化空间还原到原图尺寸对pred_logits做sigmoid后扁平化按分数从大到小排序取前num_select个配置中为 50作为最终候选将归一化的(cx,cy,w,h)框还原为(x1,y1,x2,y2)bbox_cs2xyxy并乘以输入尺寸[img_w, img_h, img_w, img_h]还原坐标关键点同样取 top-k 后乘以[img_w, img_h]最终输出形状为(num_select, num_keypoints, 2)的关键点坐标与(num_select, num_keypoints)的分数矩阵。该编解码器的行为在 tests/test_codecs/test_edpose_label.py 中有完整单测覆盖test_encode验证关键点与面积的归一化结果test_decode验证num_select与num_keypoints的输出形状。以num_select2, num_keypoints2为例decode 后关键点形状为(2, 2, 2)、分数形状为(2, 2)与设计一致。使用方式权重转换、评测与推理由于仓库提供的是官方转换权重最直接的使用方式是运行模型库中的 yml 索引configs/body_2d_keypoint/edpose/coco/edpose_coco.yml中记录的权重链接进行测试。在 COCO val2017 上评测使用 tools/test.py单卡或 tools/dist_test.sh多卡评测例如# 单卡 python tools/test.py \ configs/body_2d_keypoint/edpose/coco/edpose_res50_8xb2-50e_coco-800x1333.py \ https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/edpose/coco/edpose_res50_coco_3rdparty.pth # 8 卡分布式 bash tools/dist_test.sh \ configs/body_2d_keypoint/edpose/coco/edpose_res50_8xb2-50e_coco-800x1333.py \ https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/edpose/coco/edpose_res50_coco_3rdparty.pth \ 8评测前请确认已准备好 COCO 数据data/coco/下的annotations/person_keypoints_train2017.json与person_keypoints_val2017.json对应图像目录train2017/、val2017/数据根目录在配置中以data_root data/coco/声明并满足mmengine0.8.2的版本要求。单张图片推理也可使用仓库通用的 inferencer 进行单图/多图推理ED-Pose 模型以 bottom-up 方式直接对整图预测全部人体关键点python demo/inferencer_demo.py tests/data/coco/000000000785.jpg \ configs/body_2d_keypoint/edpose/coco/edpose_res50_8xb2-50e_coco-800x1333.py \ --weights https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/edpose/coco/edpose_res50_coco_3rdparty.pth \ --draw-heatmapPose2DInferencermmpose/apis/inferencers/pose2d_inferencer.py会自动根据配置文件中的data_modebottomup走 bottom-up 推理路径无需额外提供检测器。更完整的 API 与命令行用法可参考 docs/zh_cn/user_guides/inference.md。复现结果评测得到的 COCO 指标应与模型卡片一致AP 0.716、AP0.5 0.897、AP0.75 0.783、AR 0.793、AR0.5 0.943。评测器CocoMetric已在配置中设为nms_modenone、score_modekeypoint与 ED-Pose 端到端、免 NMS 的特性匹配。总结ED-Pose 是 MMPose 中一个颇具代表性的端到端 Transformer多人姿态估计模型它通过显式人体框检测把多人检测与关键点回归统一到同一个解码器内用查询展开机制将人框查询扩展为关键点查询并以去噪训练加速收敛。当前仓库提供了 ResNet-50 骨干的 COCO 转换权重AP 0.716相关资源包括模型配置configs/body_2d_keypoint/edpose/coco/edpose_res50_8xb2-50e_coco-800x1333.py模型索引configs/body_2d_keypoint/edpose/coco/edpose_coco.ymlHead 实现mmpose/models/heads/transformer_heads/edpose_head.pyCodec 实现与单测mmpose/codecs/edpose_label.py、tests/test_codecs/test_edpose_label.py使用前务必记住模型卡片标注的两点约束当前仅支持推理与评测权重由官方仓库转换训练将在后续版本支持配置为纯 Python 风格需mmengine0.8.2。若要在其他数据集或骨干上使用 ED-Pose可参照本文的配置结构替换dataset与backbone字段但需等待官方对训练路径的后续支持。【免费下载链接】mmposeOpenMMLab Pose Estimation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmpose创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考