- 人工智能
- 计算机视觉
- 深度学习
【免费下载链接】ViTPose
The official repo for [NeurIPS'22] "ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation" and [TPAMI'23] "ViTPose++: Vision Transformer for Generic Body Pose Estimation"
导读
本文以 ViTPose 仓库中 hrnet_udp_coco.md 为核心,系统讲解基于 HRNet 骨干与 UDP(Unbiased Data Processing,无偏数据处理)的 top-down 人体姿态估计方案:包括 COCO val2017 上的完整 benchmark 结果、可直接复用的五份配置文件逐段解读,以及 UDP 在仿射变换、热图目标生成与坐标解码三个环节的源码级实现原理。读完本文,你将能够理解use_udp=True到底改写了哪些数据处理步骤,并掌握如何在 ViTPose 仓库中配置、训练、评估与推理 HRNet+UDP 姿态估计模型。
1. HRNet 与 UDP:两篇奠基工作的组合
文档首先以算法引用块的形式确认了该配置的技术来源,这是理解后续所有配置项的前提:
- HRNet(Deep High-Resolution Representation Learning for Human Pose Estimation,CVPR'2019):全程保持高分辨率特征表示,通过多分支并行与反复的信息交换,避免了下采样-上采样结构带来的空间细节损失,是本文所有模型共用的骨干网络。
- UDP(The Devil Is in the Details: Delving Into Unbiased Data Processing for Human Pose Estimation,CVPR'2020):指出传统姿态估计数据处理流程中存在三类偏差——坐标系统偏差(coordinate system bias)、关键点位置偏差(keypoint location bias)与基于仿射变换的数据增广偏差(augmentation bias),并逐一给出无偏化改造,即本文配置中
use_udp=True的含义。 - COCO(Microsoft COCO: Common Objects in Context,ECCV'2014):提供 17 个身体关键点标注的通用目标检测与姿态估计数据集,是本文 benchmark 的评测基准。
三者组合即为文档标题所示“HRNet + UDP”的 top-down 姿态估计方案。该组合的本质是:用 HRNet 保持高分辨率特征,用 UDP 保证数据处理全程无偏,二者叠加可稳定带来精度提升。
2. COCO val2017 Benchmark 结果
文档给出了统一的评测前提:
Results on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset
即所有结果均基于同一个行人检测器(其 human AP 为 56.4)生成的检测框。在 ViTPose 仓库中,这一检测结果对应配置项bbox_file = 'data/coco/person_detection_results/COCO_val2017_detections_AP_H_56_person.json',说明评测采用检测框而非 GT 框(use_gt_bbox=False),因此表中的 AP/AR 是"检测+姿态"端到端链路下的真实指标。
五个配置的完整结果如下(数据全部来自原文档):
| 架构 | 输入尺寸 | AP | AP⁵⁰ | AP⁷⁵ | AR | AR⁵⁰ | ckpt | log |
|---|---|---|---|---|---|---|---|---|
| pose_hrnet_w32_udp | 256x192 | 0.760 | 0.907 | 0.827 | 0.811 | 0.945 | hrnet_w32_coco_256x192_udp-aba0be42_20210220.pth | hrnet_w32_coco_256x192_udp_20210220.log.json |
| pose_hrnet_w32_udp | 384x288 | 0.769 | 0.908 | 0.833 | 0.817 | 0.944 | hrnet_w32_coco_384x288_udp-e97c1a0f_20210223.pth | hrnet_w32_coco_384x288_udp_20210223.log.json |
| pose_hrnet_w48_udp | 256x192 | 0.767 | 0.906 | 0.834 | 0.817 | 0.945 | hrnet_w48_coco_256x192_udp-2554c524_20210223.pth | hrnet_w48_coco_256x192_udp_20210223.log.json |
| pose_hrnet_w48_udp | 384x288 | 0.772 | 0.910 | 0.835 | 0.820 | 0.945 | hrnet_w48_coco_384x288_udp-0f89c63e_20210223.pth | hrnet_w48_coco_384x288_udp_20210223.log.json |
| pose_hrnet_w32_udp_regress | 256x192 | 0.758 | 0.908 | 0.823 | 0.812 | 0.943 | hrnet_w32_coco_256x192_udp_regress-be2dbba4_20210222.pth | hrnet_w32_coco_256x192_udp_regress_20210222.log.json |
表格可读出的关键信息:
- 同骨干下,输入分辨率从 256x192 提升到 384x288普遍带来约 +0.009 的 AP 提升(w32:0.760→0.769;w48:0.767→0.772)。
- 同分辨率下,w48 比 w32 更宽(stage 输出通道数更高),AP 提升约 +0.007(256x192)与 +0.003(384x288)。
- 最后一行的
udp_regress是回归变体,采用 UDP 的 CombinedTarget(分类响应图 + 偏移回归图)监督,256x192 下 AP 0.758,与同尺寸 GaussianHeatmap 版(0.760)基本持平。
文档末尾特别说明了一条重要事实:
Note that, UDP also adopts the unbiased encoding/decoding algorithm of DARK (CVPR'2020)。
即 UDP 方案同时吸收了 DARK(Distribution-Aware Coordinate Representation)的无偏编码/解码思想,下文第 5 节将展示这一思想在仓库源码中的具体落点(post_dark_udp)。
3. 配置文件逐段解析:以 256x192 为例
所有 UDP 配置均继承两份基础配置:
_base_ = [ '../../../../_base_/default_runtime.py', '../../../../_base_/datasets/coco.py' ]- default_runtime.py:提供日志(
TextLoggerHook,每 50 iter)、checkpoint(每 10 epoch)、workflow = [('train', 1)]、dist_params = dict(backend='nccl')等运行期设置。 - coco.py:提供完整的 COCO 数据集元信息,包括 17 个关键点的名称与左右交换对(
flip_pairs,如left_eye/right_eye)、joint_weights(对肘、腕、膝、踝加权更高,权重最高 1.5)以及 OKS 评估所需的sigmas数组。
3.1 优化器与学习率调度
evaluation = dict(interval=10, metric='mAP', save_best='AP') optimizer = dict(type='Adam', lr=5e-4,) optimizer_config = dict(grad_clip=None) lr_config = dict( policy='step', warmup='linear', warmup_iters=500, warmup_ratio=0.001, step=[170, 200]) total_epochs = 210- 优化器选用Adam,初始学习率 5e-4,不做梯度裁剪;UDP 训练总时长210 epochs。
- 学习率采用step 策略,在第 170 与第 200 epoch 各衰减一次;前 500 个 iter 做线性 warmup,起始比例为 0.001。
- 每 10 个 epoch 在验证集上计算 mAP,并按
AP指标保存最优模型。
3.2 通道配置与骨干网络
channel_cfg = dict( num_output_channels=17, dataset_joints=17, dataset_channel=[[0, 1, ..., 16]], inference_channel=[0, 1, ..., 16])COCO 共 17 个关键点,输入通道与推理通道一一对应、无需重排。骨干为 HRNet-w32,其extra参数完整定义了四个 stage 的分支结构:
backbone=dict( type='HRNet', in_channels=3, extra=dict( stage1=dict(num_modules=1, num_branches=1, block='BOTTLENECK', num_blocks=(4, ), num_channels=(64, )), stage2=dict(num_modules=1, num_branches=2, block='BASIC', num_blocks=(4, 4), num_channels=(32, 64)), stage3=dict(num_modules=4, num_branches=3, block='BASIC', num_blocks=(4, 4, 4), num_channels=(32, 64, 128)), stage4=dict(num_modules=3, num_branches=4, block='BASIC', num_blocks=(4, 4, 4, 4), num_channels=(32, 64, 128, 256))))从 stage1(单分支、BOTTLENECK、64 通道)逐步扩展到 stage4(4 分支并行、32/64/128/256 通道),"w32"即指 stage4 中最小分支宽度为 32。pretrained 权重来自 HRNet 的 ImageNet 预训练模型。骨干结构实现位于 mmpose/models/backbones/hrnet.py。
3.3 关键点头与测试配置
keypoint_head=dict( type='TopdownHeatmapSimpleHead', in_channels=32, out_channels=channel_cfg['num_output_channels'], num_deconv_layers=0, extra=dict(final_conv_kernel=1, ), loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True)) test_cfg=dict( flip_test=True, post_process='default', shift_heatmap=False, target_type=target_type, modulate_kernel=11, use_udp=True)- 头部为
TopdownHeatmapSimpleHead:不进行反卷积上采样(num_deconv_layers=0),直接从 HRNet 的 32 通道高分辨率分支用 1x1 卷积输出 17 通道热图;训练损失为带target_weight(按关键点可见性加权)的JointsMSELoss。 test_cfg中的use_udp=True是本文核心开关:测试时开启水平翻转测试(flip_test=True)、DARK 风格调制核modulate_kernel=11(与训练 sigma=2 匹配;384x288 版为 17,对应 sigma=3)、关闭传统 0.25 像素移位(shift_heatmap=False,因为 UDP 走的是另一条解码分支)。
3.4 数据配置与 pipeline
data_cfg = dict( image_size=[192, 256], heatmap_size=[48, 64], num_output_channels=17, num_joints=17, soft_nms=False, nms_thr=1.0, oks_thr=0.9, vis_thr=0.2, use_gt_bbox=False, det_bbox_thr=0.0, bbox_file='data/coco/person_detection_results/COCO_val2017_detections_AP_H_56_person.json')image_size=[192, 256]与heatmap_size=[48, 64]的对应关系是理解 UDP 的关键:UDP 下特征图与输入图按"像素中心对齐"缩放,步长为 (256-1)/(64-1)=4.048,而非传统方案的 256/64=4(详见第 5 节)。评测时禁用 soft-NMS、使用检测器输出的 JSON 检测框文件。
训练 pipeline 完整如下(验证/测试 pipeline 与之类似,仅去掉随机翻转、半身采样与目标生成):
train_pipeline = [ dict(type='LoadImageFromFile'), dict(type='TopDownRandomFlip', flip_prob=0.5), dict(type='TopDownHalfBodyTransform', num_joints_half_body=8, prob_half_body=0.3), dict(type='TopDownGetRandomScaleRotation', rot_factor=40, scale_factor=0.5), dict(type='TopDownAffine', use_udp=True), dict(type='ToTensor'), dict(type='NormalizeTensor', mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), dict(type='TopDownGenerateTarget', sigma=2, encoding='UDP', target_type=target_type), dict(type='Collect', keys=['img', 'target', 'target_weight'], meta_keys=[...]), ]其中两个use_udp/encoding='UDP'开关即 UDP 的训练期落点:
TopDownAffine(use_udp=True):用无偏仿射矩阵get_warp_matrix替代传统get_affine_transform;TopDownGenerateTarget(encoding='UDP', sigma=2):用 UDP 方式在热图坐标系中放置高斯核。
数据增强还包括 50% 概率水平翻转、30% 概率半身采样(至少 8 个可见关键点)、±40° 旋转与 ±0.5 倍尺度缩放。
数据集部分统一使用TopDownCocoDataset(实现在 topdown_coco_dataset.py,继承自Kpt2dSviewRgbImgTopDownDataset),train2017 用于训练、val2017 用于验证与测试,训练 batch 为 64(验证/测试 batch 为 32)。
4. 五种配置的横向对比
| 配置文件 | 输入尺寸 | 热图尺寸 | target_type | sigma | modulate_kernel | 头部输出通道 |
|---|---|---|---|---|---|---|
| hrnet_w32_coco_256x192_udp.py | 256x192 | 64x48 | GaussianHeatmap | 2 | 11 | 17 |
| hrnet_w32_coco_384x288_udp.py | 384x288 | 96x72 | GaussianHeatmap | 3 | 17 | 17 |
| hrnet_w48_coco_256x192_udp.py | 256x192 | 64x48 | GaussianHeatmap | 2 | 11 | 17 |
| hrnet_w48_coco_384x288_udp.py | 384x288 | 96x72 | GaussianHeatmap | 3 | 17 | 17 |
| hrnet_w32_coco_256x192_udp_regress.py | 256x192 | 64x48 | CombinedTarget | — | 11 | 51(3×17) |
两点规律值得注意:
- 高分辨率配置使用更大的高斯 sigma 与调制核:384x288 版 sigma=3、
modulate_kernel=17,与源码注释K=17 for sigma=3 and k=11 for sigma=2完全对应(top_down_eval.py 中kernel参数说明),保证训练热图与测试时 DARK 调制的高斯核宽度一致。 - 回归变体切换为 CombinedTarget:
target_type='CombinedTarget'、头部输出3*17=51通道、损失换为CombinedTargetMSELoss。其监督由"分类响应图 + x/y 偏移回归图"三通道组成,对应 UDP 论文中"分类+回归"双任务设计。
5. UDP 源码级原理:无偏数据处理的三处落点
UDP 的改进贯穿"仿射变换 → 目标生成 → 坐标解码"三个环节,在 ViTPose 仓库中均有明确的实现与测试支撑。
5.1 无偏仿射变换:get_warp_matrix
传统get_affine_transform以像素角点(corner)为对齐基准,导致不同分辨率间存在约半个像素的尺度偏差。UDP 改为像素中心对齐。TopDownAffine在use_udp=True时调用:
trans = get_warp_matrix(r, c * 2.0, image_size - 1.0, s * 200.0)对应实现位于 post_transforms.py:get_warp_matrix直接按旋转角 θ 构造 2x3 矩阵,缩放系数取size_dst / size_target,并从中心0.5 * size_input处出发做旋转平移,从而消除角点对齐引入的坐标偏差。这一点在源码 docstring 中明确标注为 "Calculate the transformation matrix under the constraint of unbiased"。
5.2 无偏目标生成:_udp_generate_target
TopDownGenerateTarget在encoding='UDP'时调用_udp_generate_target(top_down_transform.py),其核心差异是步长定义:
feat_stride = (image_size - 1.0) / (heatmap_size - 1.0) mu_x = int(joints_3d[joint_id][0] / feat_stride[0] + 0.5)即关键点从图像坐标映射到热图坐标时,分母为heatmap_size - 1而非heatmap_size,与无偏仿射变换保持同一坐标系约定。该函数支持两种target_type:
- GaussianHeatmap:在 48x64 热图上以 sigma 为高斯半径放置响应峰,
factor * 3为高斯截断半径,并按可见性写入target_weight; - CombinedTarget:为每个关键点生成 3 张图——分类响应图(半径内置 1)与 x/y 偏移图(归一化到 valid_radius 内),
valid_radius = factor * heatmap_size[1],最终 reshape 为3*K, H, W。
target_type的合法性校验('GaussianHeatmap'或'CombinedTarget')也在该函数内完成。
5.3 无偏解码:transform_preds + keypoints_from_heatmaps
测试/验证阶段,keypoints_from_heatmaps(top_down_eval.py)在use_udp=True时走独立分支:
- GaussianHeatmap 分支:先取最大值位置,再调用
post_dark_udp(同文件 L335 起)——对热图做高斯模糊、取对数后,在最大值邻域用二阶泰勒展开求解亚像素偏移。这正是文档末尾所提"UDP also adopts the unbiased encoding/decoding algorithm of DARK"的代码落点。 - CombinedTarget 分支:对分类热图做高斯模糊(核大小随通道
i%3变化),取分类响应峰值位置,再按该位置的 x/y 偏移通道加回亚像素偏移,即"分类定位 + 偏移回归"联合解码。
最后通过transform_preds(post_transforms.py)映射回原图坐标。use_udp=True时其缩放分母同样为output_size - 1:
scale_x = scale[0] / (output_size[0] - 1.0) # UDP scale_x = scale[0] / output_size[0] # 传统scale先按* 200.0恢复(对应训练侧s * 200.0的归一化),再乘预测坐标并平移回center - scale * 0.5。三个环节使用同一套"像素中心、尺寸减一"的坐标系约定,正是"无偏"得以成立的原因——如果仿射、目标生成、解码各自采用不同的对齐规则,坐标偏差就会在链路中累积。
仓库测试 test_top_down_pipelines.py 对TopDownGenerateTarget的多种encoding/target_type/sigma组合进行了断言:验证了GaussianHeatmap与多 sigma 情况下 target 张量形状(如多 sigma 时为(num_sigmas, num_joints, H, W))、target_weight形状(num_joints, 1),从侧面保证了 UDP 目标生成路径的数值形状正确。
6. 训练、评估与推理实操
6.1 训练
单卡训练(需先按 data_preparation.md 准备 COCO 数据并放置检测框 JSON):
python tools/train.py configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/coco/hrnet_w32_coco_256x192_udp.py多卡分布式训练使用 dist_train.sh,第一个参数为配置、第二个为 GPU 数:
bash tools/dist_train.sh configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/coco/hrnet_w32_coco_256x192_udp.py 8训练流程由 mmpose/apis/train.py 驱动:build_optimizers构造 Adam 优化器,EpochBasedRunner注册学习率与优化器钩子,并注册DistEvalHook/EvalHook按evaluation.interval=10在验证集上评测,runner.run(data_loaders, cfg.workflow, cfg.total_epochs)运行 210 个 epoch。
6.2 评估
在 COCO val2017 上复现 benchmark(默认使用配置内bbox_file指定的检测结果):
python tools/test.py configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/coco/hrnet_w32_coco_256x192_udp.py /path/to/checkpoints/hrnet_w32_coco_256x192_udp-aba0be42_20210220.pth评估指标为 COCO mAP(OKS 相关指标族),对应evaluation = dict(metric='mAP');评估实现在 top_down_eval.py 的keypoints_from_heatmaps与 OKS 计算逻辑中。
6.3 推理
使用官方推理 APIinference_top_down_pose_model(mmpose/apis/inference.py)即可加载训练好的模型对单图执行推理:先由检测器(或手动指定)提供person_results中的人体框,内部通过_box2cs将 bbox 转为中心点与尺度,再经test_pipeline(含TopDownAffine(use_udp=True))预处理、前向得到热图,最终在_inference_single_pose_model中按配置的test_cfg完成 UDP 解码。若未提供检测框,函数会自动创建一个覆盖全图的 dummy bbox。
7. 总结
HRNet + UDP 是 ViTPose 仓库中精度与速度平衡良好的 top-down 姿态估计基线之一。从本文的 benchmark 与源码分析可以看出:
- 配置侧:UDP 只需在 pipeline 与
test_cfg中打开三个开关——TopDownAffine(use_udp=True)、TopDownGenerateTarget(encoding='UDP')、test_cfg.use_udp=True,其余训练策略与标准 HRNet 保持一致。 - 原理侧:UDP 在仿射变换(
get_warp_matrix)、目标生成(_udp_generate_target)与坐标解码(transform_preds+post_dark_udp)三处统一采用"像素中心、尺寸减一"的坐标系约定,消除了传统流程中的三类坐标偏差。 - 扩展侧:
udp_regress变体通过CombinedTarget将分类与偏移回归联合监督引入同一框架;输入分辨率与高斯 sigma/调制核的对应关系(2↔11、3↔17)为复现与调参提供了明确参照。
如需进一步对比,可查阅同目录下的 hrnet_coco.md(标准 HRNet)、hrnet_dark_coco.md(DARK 无偏编码)等 benchmark 文档,观察不同数据处理方案在同骨干下的精度差异。
- 人工智能
- 计算机视觉
- 深度学习
【免费下载链接】ViTPose
The official repo for [NeurIPS'22] "ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation" and [TPAMI'23] "ViTPose++: Vision Transformer for Generic Body Pose Estimation"
相关推荐
基于 HRNet 的 COCO 人体姿态估计:ViTPose 仓库 topdown heatmap 配置全解析
基于 HRNet 的 COCO 人体姿态估计:ViTPose 仓库 topdown heatmap 配置全解析 导读 本文以 ViTPose 仓库中 hrnet
人工智能计算机视觉深度学习ViTPose 仓库中 HRNet + DARK 在 COCO 上的姿态估计配置详解与源码原理
ViTPose 仓库中 HRNet + DARK 在 COCO 上的姿态估计配置详解与源码原理 本文以仓库 configs/body/2d_kpt_sview_
人工智能计算机视觉深度学习ViTPose 仓库 Associative Embedding + HRNet COCO 自底向上人体姿态估计配置全解析
ViTPose 仓库 Associative Embedding + HRNet COCO 自底向上人体姿态估计配置全解析 导读 本文以 hrnet_coco.
人工智能计算机视觉深度学习
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考