☰
ViTPose 中的 HRNet 马姿态估计实战:Horse-10 数据集 Top-down Heatmap 配置解析与模型选型指南
2026/10/13 15:17:10 网站建设 项目流程
  • 人工智能
  • 计算机视觉
  • 深度学习

【免费下载链接】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"

项目地址:https://gitcode.com/gh_mirrors/vi/ViTPose
点击查看免费下载

本文围绕 ViTPose 仓库中 Horse-10 动物姿态估计的 HRNet 基准文档 hrnet_horse10.md 展开,系统讲解如何在动物 2D 关键点检测任务中使用 HRNet(CVPR'2019)作为高分辨率特征骨干:从官方 PCK/NME 基准结果出发,深入剖析 w32 与 w48 两套配置文件的模型结构、训练策略与数据增强差异,并给出可直接运行的训练、测试命令与评测指标实现依据。读完后,你可以独立完成 Horse-10 数据集上的 HRNet 模型复现、按 split 划分做基准测试,并根据精度/速度需求选择合适的 backbone 宽度。

一、任务背景:HRNet 与 Horse-10 数据集

该基准文档关联两篇论文:

骨干网络——HRNet(CVPR'2019),通过多分辨率并行分支与跨分辨率交互保持高分辨率表征,从源码结构看其实现位于 hrnet.py,在 top-down heatmap 范式中与TopdownHeatmapSimpleHead配合输出关键点热图:

@inproceedings{sun2019deep, title={Deep high-resolution representation learning for human pose estimation}, author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong}, booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition}, pages={5693--5703}, year={2019} }

数据集——Horse-10(WACV'2021),来源于 Mathis 等人的预训练鲁棒性研究,用于非人类(马)2D 姿态估计:

@inproceedings{mathis2021pretraining, title={Pretraining boosts out-of-domain robustness for pose estimation}, author={Mathis, Alexander and Biasi, Thomas and Schneider, Steffen and Yuksekgonul, Mert and Rogers, Byron and Bethge, Matthias and Mathis, Mackenzie W}, booktitle={Proceedings of the IEEE/CVF Winter Conference on Applications of Computer Vision}, pages={1859--1868}, year={2021} }

ViTPose 继承自 MMPose 的 animal 任务体系(任务总览见 2D Animal Keypoint Detection),将 Horse-10 归类于2d_kpt_sview_rgb_img/topdown_heatmap技术路线:先由检测器(或使用预标注 bbox)框出单只马,再对每个 bbox 做关键点热图回归。

二、官方基准结果

原始文档在 Horse-10 测试集上给出了 6 组 HRNet 官方结果,完整继承如下:

SetArchInput SizePCK@0.3NMEckptlog
split1pose_hrnet_w32256x2560.9510.122ckptlog
split2pose_hrnet_w32256x2560.9490.116ckptlog
split3pose_hrnet_w32256x2560.9390.153ckptlog
split1pose_hrnet_w48256x2560.9730.095ckptlog
split2pose_hrnet_w48256x2560.9690.101ckptlog
split3pose_hrnet_w48256x2560.9610.128ckptlog

从结果可以看出两点选型经验:其一,w48 在三个 split 上均优于 w32(PCK@0.3 提升约 2~3 个点,NME 降低约 0.03),适合追求极限精度;其二,split3 在两种宽度下都是三个划分中最难的(NME 最高),这与数据集划分中不同马匹/场景差异有关,评估时应以多个 split 综合判断而非单一 split。该表中记录的指标与 hrnet_horse10.yml 模型库索引一一对应(Task: Animal 2D Keypoint)。

三、Horse-10 数据集结构:22 个关键点与骨骼连接

数据集元信息集中定义在 horse10.py 的dataset_info中。Horse-10 共有22 个关键点,按语义可分为头部(Nose、Eye)、躯干(Shoulder、Midshoulder、Elbow、Girth、Wither、Hip、Ischium、Stifle)以及四肢(前后腿的 knee/fetlock/foot/hock):

ID关键点ID关键点
0Nose11Girth
1Eye12Wither
2Nearknee13Nearhindhock
3Nearfrontfetlock14Nearhindfetlock
4Nearfrontfoot15Nearhindfoot
5Offknee16Hip
6Offfrontfetlock17Stifle
7Offfrontfoot18Offhindhock
8Shoulder19Offhindfetlock
9Midshoulder20Offhindfoot
10Elbow21Ischium

skeleton_info定义了 18 条骨骼连线,例如Nose→Eye、Eye→Wither、Wither→Hip构成躯干主轴,Nearknee→Nearfrontfetlock→Nearfrontfoot构成前腿链条,用于可视化渲染;joint_weights为 22 个关键点统一赋权 1.0,即评测时各关节等权。由于马的姿态左右基本对称,flip_pairs在数据集中为空(swap=''),这意味着水平翻转增强时不做关键点互换——这一细节在 animal_horse10_dataset.py 中通过继承 top-down 基类的通用翻转逻辑处理。

数据下载与目录组织

按 2d_animal_keypoint.md 的说明,图像可从 Horse-10 官方主页下载,标注文件为 OpenMMLab 提供的horse10_annotations.tar,该数据仅限非商业使用。期望目录结构为:

mmpose │── data │── horse10 │── annotations │ │-- horse10-train-split1.json │ |-- horse10-train-split2.json │ |-- horse10-train-split3.json │ │-- horse10-test-split1.json │ |-- horse10-test-split2.json │ |-- horse10-test-split3.json │── train/ │── test/

配置文件中的数据根目录即data/horse10(见 hrnet_w32_horse10_256x256-split1.py 中data_root = 'data/horse10'),train/val/test 分别读取对应 split 的 json 文件。

四、模型配置文件深度解析

以 hrnet_w32_horse10_256x256-split1.py 为基准(w48 及 split2/3 的差异见后文):

4.1 继承关系与训练策略

_base_ = [ '../../../../_base_/default_runtime.py', '../../../../_base_/datasets/horse10.py' ] evaluation = dict(interval=10, metric='PCK', save_best='PCK')

配置继承 default_runtime.py 的默认运行时参数与 horse10.py 的数据集元信息;每 10 个 epoch 评测一次 PCK 并保存最优权重。

学习率与调度:

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,无梯度裁剪;
  • 前 500 次迭代线性 warmup(从 0.001 倍升温至全量);
  • 210 个 epoch 内于 170、200 epoch 处按 step 策略衰减学习率。

4.2 骨干网络:HRNet 多分辨率结构

w32 与 w48 的差异体现在 HRNetextra的各 stage 通道数:

部位w32w48
stage2 num_channels(32, 64)(48, 96)
stage3 num_channels(32, 64, 128)(48, 96, 192)
stage4 num_channels(32, 64, 128, 256)(48, 96, 192, 384)
head in_channels3248
ImageNet 预训练权重hrnet_w32-36af842e.pthhrnet_w48-8ef0771d.pth

stage1 统一采用 1 个 BOTTLENECK 分支、64 通道;stage2/3/4 分别使用 2/3/4 个并行分支做跨分辨率融合,各 stage 的 module 数为 1/4/3,每分支块数均为 4。两套配置分别从 ImageNet 预训练的hrnet_w32、hrnet_w48checkpoint 初始化(pretrained字段),这也是该任务“预训练提升跨域鲁棒性”主题的落地方式。

关键点头与损失:

keypoint_head=dict( type='TopdownHeatmapSimpleHead', in_channels=32, # w48 配置中为 48 out_channels=channel_cfg['num_output_channels'], # 22 num_deconv_layers=0, extra=dict(final_conv_kernel=1, ), loss_keypoint=dict(type='JointsMSELoss', use_target_weight=True)),
  • num_deconv_layers=0:不加反卷积上采样层,HRNet 本身保持高分辨率(1/4 下采样);
  • final_conv_kernel=1:末端为 1×1 卷积直接输出 22 通道热图;
  • JointsMSELoss+use_target_weight=True:按关键点可见性加权的热图 MSE 损失。

4.3 输入输出尺寸与通道映射

data_cfg = dict( image_size=[256, 256], heatmap_size=[64, 64], ...)

输入裁剪框 256×256,热图 64×64,即 4 倍下采样,与 HRNet 主干的 1/4 分辨率特征天然对齐。channel_cfg将 22 个关节(ID 20 即 Offhindfoot 因索引跳过 20 位)映射到单一输出通道组,训练与推理通道一致。

4.4 数据增强流水线

train_pipeline = [ dict(type='LoadImageFromFile'), dict(type='TopDownRandomFlip', flip_prob=0.5), dict(type='TopDownGetRandomScaleRotation', rot_factor=40, scale_factor=0.5), dict(type='TopDownAffine'), 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), dict(type='Collect', keys=['img', 'target', 'target_weight'], meta_keys=['image_file', 'joints_3d', 'joints_3d_visible', 'center', 'scale', 'rotation', 'bbox_score', 'flip_pairs']) ]

关键增强项(实现均在 top_down_transform.py):

  • TopDownRandomFlip:50% 概率水平翻转;
  • TopDownGetRandomScaleRotation:随机旋转 ±40°、随机缩放 0.5 倍(±50%),用于增强对马匹姿态方向/距离的鲁棒性;
  • TopDownGenerateTarget:以 sigma=2 的高斯核生成热图监督目标。

验证/测试流水线val_pipeline仅做TopDownAffine裁剪 + 归一化,无随机增强。

4.5 测试期配置

test_cfg=dict( flip_test=True, post_process='default', shift_heatmap=True, modulate_kernel=11)
  • flip_test=True:对翻转后的输入再推理一次并将热图翻回,从源码看由 topdown_heatmap_simple_head.py 的inference_model中flip_back完成;
  • shift_heatmap=True:翻转热图存在 1 像素特征错位,推理时对翻转热图左移一列以对齐(源码注释 “feature is not aligned, shift flipped heatmap for higher accuracy”);
  • post_process='default'与modulate_kernel=11:启用热图后处理(modulate/unsuppress 策略),kernel 大小 11。

4.6 批大小设置

data = dict( samples_per_gpu=64, workers_per_gpu=2, val_dataloader=dict(samples_per_gpu=32), test_dataloader=dict(samples_per_gpu=32), ...)

由于每张马的照片只产生 1~2 个 bbox,22 关键点热图体积较小,训练批大小可开到 64。

五、数据集加载与评测实现的源码佐证

AnimalHorse10Dataset 继承Kpt2dSviewRgbImgTopDownDataset,有两个值得注意的实现细节:

1)bbox 输入使用 1.25 倍 padding:

# use 1.25 padded bbox as input center, scale = self._xywh2cs(*obj['bbox'][:4], 1.25)

加载标注时即对原 bbox 放大 1.25 倍再求 center/scale,保证马匹四肢(fetlock、foot 等边缘关节)尽量不落在裁剪框外。

2)NME 归一化因子为双眼间距:

def _get_normalize_factor(self, gts): interocular = np.linalg.norm(gts[:, 0, :] - gts[:, 1, :], axis=1, keepdims=True) return np.tile(interocular, [1, 2])

即 Nose(0) 与 Eye(1) 两点间的欧氏距离,把误差归一到与马头尺寸相当的比例尺度上,这正是 Horse-10 论文推荐的做法,也解释了结果表中 NME 在 0.095~0.153 区间的含义。

3)评测指标:evaluate(metric='PCK' | 'NME')走基类 _report_metric,底层调用 top_down_eval.py 的keypoint_pck_accuracy与keypoint_nme。PCK 以 bbox 最大边长为归一化参考、pck_thr为判定阈值;基准表标注的 PCK@0.3 对应阈值 0.3(_report_metric的pck_thr参数在源码中默认值为 0.2,基准测试按 0.3 口径统计,引用指标时应以原始文档表格的 PCK@0.3 口径为准)。评测结果写入result_keypoints.json并支持res_folder持久化。

六、训练、测试与推理命令

6.1 训练

以 w48/split1 为例(需先在仓库根目录准备好上文第三节所述的data/horse10):

python tools/train.py configs/animal/2d_kpt_sview_rgb_img/topdown_heatmap/horse10/hrnet_w48_horse10_256x256-split1.py

多卡训练可加--gpus N参数,或改用 dist_train.sh 分布式脚本;total_epochs=210、学习率在 170/200 epoch 衰减,与--runner默认 epoch 模式一致。

6.2 测试

python tools/test.py configs/animal/2d_kpt_sview_rgb_img/topdown_heatmap/horse10/hrnet_w48_horse10_256x256-split1.py CHECKPOINT --eval PCK NME

--eval支持PCK与NME两种指标(源码中allowed_metrics = ['PCK', 'NME']),evaluation.metric='PCK'保证训练过程中自动按 PCK 保存最优 checkpoint。

6.3 推理

仓库提供 top-down 动物推理脚本 top_down_img_demo.py,文档见 2d_animal_demo.md:加载上述 HRNet checkpoint,输入单张马的图片(需给出 bbox 或使用检测结果),输出 22 个关键点与骨骼渲染图。

七、小结

决策点建议
精度优先hrnet_w48_*,三 split 平均 PCK@0.3 ≈ 0.968,NME ≈ 0.108
速度/资源优先hrnet_w32_*,精度损失约 2~3 个 PCK 点
泛化性评估三个 split 都要测,split3 最困难
自定义微调复用lr_config(5e-4 Adam、170/200 step)与 1.25× bbox padding 设定

如需扩展,同一目录下还有 ResNet 系列对照配置(resnet_horse10.md),可作为 HRNet 之外的 baseline 参照;数据集元信息、关键点/骨骼定义与AnimalHorse10Dataset源码共同构成了该任务从数据到评测的完整证据链。

  • 人工智能
  • 计算机视觉
  • 深度学习

【免费下载链接】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"

项目地址:https://gitcode.com/gh_mirrors/vi/ViTPose
点击查看免费下载

相关推荐

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

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

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

立即咨询