
MMPose 手部关键点检测实践HRNetv2-w18 UDP 在 OneHand10K 上的配置与原理全解析【免费下载链接】mmposeOpenMMLab Pose Estimation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmpose本篇文章围绕 MMPose 仓库中configs/hand_2d_keypoint/topdown_heatmap/onehand10k/hrnetv2_udp_onehand10k.md这一模型卡片展开完整解析 HRNetv2-w18 主干网络结合 UDP 无偏数据编解码的 2D 手部姿态估计方案并给出在 OneHand10K 数据集上的验证结果、完整可运行的训练配置以及底层 codec 的源码级原理。读完本文你将掌握该 topdown 热力图方案的配置结构、UDP 编解码细节与训练评估方法可直接在 MMPose 中复现该模型。一、模型卡片概览一次读懂算法 数据集 配置三要素该模型卡片位于 configs/hand_2d_keypoint/topdown_heatmap/onehand10k/hrnetv2_udp_onehand10k.md属于 MMPose 中 top-down heatmap 系列的手部关键点模型。它明确引用了三篇核心工作组成部分论文出处主干网络HRNetv2Deep High-Resolution Representation Learning for Visual RecognitionTPAMI2019编解码UDPThe Devil is in the Details: Delving Into Unbiased Data Processing for Human Pose EstimationCVPR2020数据集OneHand10KMask-pose Cascaded CNN for 2D Hand Pose Estimation from Single Color ImageTCSVT2019该配置对应的模型是td-hm_hrnetv2-w18_udp-8xb64-210e_onehand10k-256x256完整模型定义与训练参数位于 td-hm_hrnetv2-w18_udp-8xb64-210e_onehand10k-256x256.py。从文件命名即可读出核心要素td-hmtop-down heatmap 范式、hrnetv2-w1818 通道宽度的 HRNetv2、udpUDP 编解码、8xb648 卡 × batch size 64、210e210 个 epoch、256x256输入分辨率。OneHand10K 验证集上的表现原模型卡片给出的 OneHand10K val 集结果如下ArchInput SizePCK0.2AUCEPEckptlogpose_hrnetv2_w18_udp256x2560.9900.57123.88见 hrnetv2_udp_onehand10k.yml见 hrnetv2_udp_onehand10k.yml三个指标的含义如下PCK0.2以关键点所在图像区域尺寸的 20% 为阈值预测点与真值距离小于阈值的比例取值 0~1越高越好。此处 0.990 表示 99% 的关键点预测误差落在该阈值内AUC不同 PCK 阈值下正确率的曲线下面积越高越好此处 0.571EPEEnd Point Error所有关键点预测位置与真值的平均欧氏距离像素越低越好此处 23.88。作为横向参照同一数据集上其他配置的对比记录在 configs/hand_2d_keypoint/topdown_heatmap/README.mdHRNetv2-w18 Dark 为 PCK0.20.990 / AUC0.572 / EPE23.96纯 HRNetv2-w18 为 0.990 / 0.567 / 24.26ResNet-50 为 0.989 / 0.555 / 25.16MobileNet-v2 为 0.986 / 0.537 / 28.56。UDP 相对基础 MSRA 编解码在 AUC 与 EPE 上均有改善印证了无偏数据处理带来的坐标精度收益。二、UDP 无偏编解码原理从配置文件到源码实现UDP 的核心思想是消除传统 heatmap 方法中由坐标取整、仿射变换与量化引入的系统性偏差。在 MMPose 中它由 codec 模块实现配置文件里只声明一行# codec settings codec dict( typeUDPHeatmap, input_size(256, 256), heatmap_size(64, 64), sigma2)2.1 关键参数说明参数配置值含义typeUDPHeatmapcodec 类型在 mmpose/codecs/udp_heatmap.py 中注册input_size(256, 256)网络输入图像尺寸[w, h]heatmap_size(64, 64)热力图分辨率[W, H]即 4 倍下采样sigma2高斯热力图标准差默认 2.0heatmap_typegaussian默认编码方式可选gaussian或combined偏移图 二值标签图radius_factor0.0546875默认combined模式下正样本区域半径因子blur_kernel_size11默认DarkPose 式热力图调制的高斯模糊核大小2.2 编码encode无偏高斯热力图生成UDPHeatmap.encode接收输入图像坐标系下的关键点坐标先按下式将坐标从输入空间映射到热力图空间self.scale_factor ((np.array(input_size) - 1) / (np.array(heatmap_size) - 1)).astype(np.float32)注意这里使用的是(input_size - 1) / (heatmap_size - 1)即保留了边界坐标与像素中心对齐关系这正是 UDP 与普通线性映射的关键差异之一。随后调用 generate_udp_gaussian_heatmaps 生成高斯热力图。与朴素实现相比UDP 的高斯生成在整数网格上保留了亚像素偏移信息mu (keypoints[n, k] 0.5).astype(np.int64) # 整数化后的中心 ... mu_ac keypoints[n, k] # 亚像素精确中心 x0 y0 gaussian_size // 2 x0 mu_ac[0] - mu[0] # 高斯核内偏移量 y0 mu_ac[1] - mu[1] gaussian np.exp(-((x - x0)**2 (y - y0)**2) / (2 * sigma**2))即高斯核的中心不是被四舍五入到整数像素而是在核内以亚像素精度偏移从而消除坐标取整引入的训练目标偏差。超出边界的点会将其keypoint_weights置 0避免无意义监督。2.3 解码decode最大响应定位 分布感知精修UDPHeatmap.decode完成推理时的坐标恢复通过 get_heatmap_maximum 在每张热力图上取最大响应位置作为初始预测调用 refine_keypoints_dark_udp 进行分布感知distribution-aware精修先对热力图做高斯模糊调制并取对数再在峰值附近用数值差分构造一阶导数与 Hessian 矩阵通过keypoints - inv(H) grad一步定位到连续坐标下的真实极值将输出精度推进到亚像素级别最后按keypoints / [W-1, H-1] * input_size将坐标映射回输入图像空间。这一解码过程在实现上与 DarkPose 的refine_keypoints_dark同源但针对 UDP 的像素中心对齐约定做了适配且在实现细节上采用了 edge padding 与向量化的einsum求逆兼顾了数值稳定性与效率。三、数据集与标注OneHand10K 的 21 点手部骨架OneHand10K 是一个大规模单目 2D 手部关键点数据集。MMPose 中其加载逻辑由 mmpose/datasets/datasets/hand/onehand10k_dataset.py 中的OneHand10KDataset类实现它继承自BaseCocoStyleDataset即标注采用 COCO 风格 JSON并通过METAINFO dict(from_fileconfigs/_base_/datasets/onehand10k.py)引用数据集元信息。数据集元信息定义在 configs/base/datasets/onehand10k.py包含完整的 21 点骨架定义索引从 0 到 20索引关键点索引关键点0wrist手腕11middle_finger3中指第 3 节1thumb1拇指第 1 节12middle_finger4中指指尖2thumb213ring_finger1无名指第 1 节3thumb314ring_finger24thumb4拇指指尖15ring_finger35forefinger1食指第 1 节16ring_finger4无名指指尖6forefinger217pinky_finger1小指第 1 节7forefinger318pinky_finger28forefinger4食指指尖19pinky_finger39middle_finger1中指第 1 节20pinky_finger4小指指尖10middle_finger2——该文件同时定义了 5 条手指链的skeleton_info腕部连接各指第 1 节、指节之间依次连接以及joint_weights[1.] * 21全部关键点等权参与损失计算。这也是配置文件中head.out_channels21的直接依据。四、完整配置文件逐段精讲下面按配置文件的逻辑分区逐一说明 td-hm_hrnetv2-w18_udp-8xb64-210e_onehand10k-256x256.py 各段的作用。4.1 运行时与优化策略_base_ [../../../_base_/default_runtime.py] # runtime train_cfg dict(max_epochs210, val_interval10) # 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) # hooks default_hooks dict(checkpointdict(save_bestAUC, rulegreater))训练轮数210 个 epoch每 10 个 epoch 做一次验证val_interval10优化器Adam初始学习率 5e-4学习率调度前 500 次迭代线性 warm-up从 0.001 倍初始 LR 爬升之后在 170/200 epoch 处按 0.1 倍阶梯衰减MultiStepLR自动缩放 LRauto_scale_lr声明了 512 的基准 batch size当实际训练的 batch size 与之不同时MMPose 会自动按比例调整学习率模型选择save_bestAUC表示按验证集 AUC 选择最优 checkpoint 保存rulegreater表示指标越大越好。default_runtime.py的基础运行时来自 configs/base/default_runtime.py提供日志、checkpoint、可视化、BadCase 分析等默认 hooks并设定default_scopemmpose以启用 MMEngine 的注册表机制。4.2 模型结构HRNetv2-w18 FeatureMapProcessor HeatmapHeadmodel dict( typeTopdownPoseEstimator, data_preprocessordict( typePoseDataPreprocessor, mean[123.675, 116.28, 103.53], std[58.395, 57.12, 57.375], bgr_to_rgbTrue), backbonedict( typeHRNet, in_channels3, extradict( stage1dict(num_modules1, num_branches1, blockBOTTLENECK, num_blocks(4, ), num_channels(64, )), stage2dict(num_modules1, num_branches2, blockBASIC, num_blocks(4, 4), num_channels(18, 36)), stage3dict(num_modules4, num_branches3, blockBASIC, num_blocks(4, 4, 4), num_channels(18, 36, 72)), stage4dict(num_modules3, num_branches4, blockBASIC, num_blocks(4, 4, 4, 4), num_channels(18, 36, 72, 144), multiscale_outputTrue), upsampledict(modebilinear, align_cornersFalse)), init_cfgdict(typePretrained, checkpointopen-mmlab://msra/hrnetv2_w18)), neckdict(typeFeatureMapProcessor, concatTrue), headdict( typeHeatmapHead, in_channels270, out_channels21, deconv_out_channelsNone, conv_out_channels(270, ), conv_kernel_sizes(1, ), lossdict(typeKeypointMSELoss, use_target_weightTrue), decodercodec), test_cfgdict( flip_testTrue, flip_modeheatmap, shift_heatmapFalse, ))关键设计点HRNetv2-w18 结构4 个 stage 并行分辨率分支数依次为 1→2→3→4通道数为 18/36/72/144各 stage 均保持高分辨率分支与低分辨率分支并行最后以multiscale_outputTrue输出多尺度特征upsample使用bilinear align_cornersFalse上采样到统一分辨率初始化主干网络使用 ImageNet 预训练权重open-mmlab://msra/hrnetv2_w18颈部聚合FeatureMapProcessor将 HRNet 输出的多尺度特征concat拼接183672144270 通道与head.in_channels270对应检测头HeatmapHead输出 21 通道热力图用 1×1 卷积conv_out_channels(270, )、conv_kernel_sizes(1, )压缩通道不使用反卷积deconv_out_channelsNone损失KeypointMSELoss均方误差use_target_weightTrue表示按 codec 生成的关键点权重加权遮挡或出界点的权重为 0测试策略flip_testTrue开启水平翻转测试flip_modeheatmap表示对热力图做翻转融合shift_heatmapFalse表示不额外做 0.5 像素偏移修正——这与 UDP 的像素中心对齐约定一致是 UDP 配置区别于普通 MSRA 配置该字段为shift_heatmapTrue的重要差异也侧面印证了 UDP 无偏设计的目标。4.3 数据流水线topdown 范式下的训练/验证流程dataset_type OneHand10KDataset data_mode topdown data_root data/onehand10k/ train_pipeline [ dict(typeLoadImage), dict(typeGetBBoxCenterScale), dict(typeRandomFlip, directionhorizontal), dict(typeRandomBBoxTransform, rotate_factor180, scale_factor(0.7, 1.3)), 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) ]topdown模式意味着检测 单人姿态估计两阶段范式本配置输入的是已经由检测器给出的手部 bbox训练时依次执行读图 → 由 bbox 计算中心点与尺度 → 水平随机翻转 → 随机 bbox 变换旋转幅度最高 180°、尺度缩放 0.7~1.3 倍对手部大范围旋转具有很好的鲁棒性→ topdown 仿射变换到 256×256 → 用UDPHeatmapcodec 生成监督目标 → 打包输入验证时不做数据增强仅做仿射变换。数据加载部分训练集使用annotations/onehand10k_train.json、batch size 64、2 个 worker 并开启persistent_workersTrue验证集使用annotations/onehand10k_test.json、batch size 32test_modeTrue。4.4 评估指标val_evaluator [ dict(typePCKAccuracy, thr0.2), dict(typeAUC), dict(typeEPE), ] test_evaluator val_evaluator验证与测试阶段同时计算 PCK0.2、AUC、EPE 三项指标与模型卡片结果表一一对应。五、从零训练与测试命令行实操MMPose 基于 MMEngine 提供统一的训练入口 tools/train.py 与测试入口 tools/test.py配合仓库根目录的分布式脚本 tools/dist_train.sh 和 tools/dist_test.sh。以下命令均在仓库根目录下执行。5.1 单卡训练python tools/train.py configs/hand_2d_keypoint/topdown_heatmap/onehand10k/td-hm_hrnetv2-w18_udp-8xb64-210e_onehand10k-256x256.py5.2 多卡8 卡训练bash tools/dist_train.sh configs/hand_2d_keypoint/topdown_heatmap/onehand10k/td-hm_hrnetv2-w18_udp-8xb64-210e_onehand10k-256x256.py 88xb64命名即对应 8 卡 × 单卡 batch size 64 512 的全局 batch size正好与auto_scale_lr.base_batch_size512对齐。5.3 测试与指标复现python tools/test.py configs/hand_2d_keypoint/topdown_heatmap/onehand10k/td-hm_hrnetv2-w18_udp-8xb64-210e_onehand10k-256x256.py checkpoint路径运行前需按 docs/zh_cn/user_guides/prepare_datasets.md 的指引将 OneHand10K 数据放置到data/onehand10k/目录下并确认目录结构符合配置文件中的ann_file与data_prefix约定。训练完成后默认按 AUC 择优保存 checkpoint日志与权重输出位置遵循 configs/base/default_runtime.py 中的默认工作目录设置。六、模型系列的延伸阅读该配置在仓库中不是孤例同目录下还提供了同一主干网络在不同编解码方案下的对照模型td-hm_hrnetv2-w18_8xb64-210e_onehand10k-256x256.py使用经典 MSRAHeatmap 编解码是 UDP 的基线对照td-hm_hrnetv2-w18_dark-8xb64-210e_onehand10k-256x256.py使用 DarkPose 编解码MSRAHeatmap dark 精修td-hm_res50_8xb32-210e_onehand10k-256x256.py 与 td-hm_mobilenetv2_8xb64-210e_onehand10k-256x256.py不同主干网络ResNet-50、MobileNet-v2的轻量/经典对照。对比各模型在 OneHand10K 上的 EPEUDP 23.88 Dark 23.96 基线 24.26 ResNet-50 25.16 MobileNet-v2 28.56可以直观看到编解码方案与主干容量对定位精度的共同影响。若需深入了解 UDP 在更多数据集如 COCO-WholeBody-Hand、RHD上的表现可参考 configs/hand_2d_keypoint/topdown_heatmap/README.md 中的完整模型清单codec 的完整参数说明与扩展指南见 docs/en/advanced_guides/codecs.md中文版 docs/zh_cn/advanced_guides/codecs.md。七、总结HRNetv2-w18 UDP 在 OneHand10K 上取得了 PCK0.20.990、AUC0.571、EPE23.88 的成绩其精度优势主要来自两个层面的无偏设计编码时高斯核在整数网格内保留亚像素偏移、解码时通过分布感知精修将坐标推进到连续域。通过本文对配置文件逐段的拆解与对 mmpose/codecs/udp_heatmap.py、mmpose/codecs/utils/gaussian_heatmap.py、mmpose/codecs/utils/refinement.py 等源码的对照你可以据此复现训练、验证结果并以此为模板迁移到其他 topdown 手部姿态估计任务中。【免费下载链接】mmposeOpenMMLab Pose Estimation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmpose创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考