news 2026/9/17 5:40:38

MMPose 人脸关键点检测实战:HRNetv2-W18 在 COCO-WholeBody-Face 数据集上的配置与实现解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MMPose 人脸关键点检测实战:HRNetv2-W18 在 COCO-WholeBody-Face 数据集上的配置与实现解析

MMPose 人脸关键点检测实战:HRNetv2-W18 在 COCO-WholeBody-Face 数据集上的配置与实现解析

【免费下载链接】mmposeOpenMMLab Pose Estimation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmpose

本篇文章以 hrnetv2_coco_wholebody_face.md 模型卡片为核心,结合 MMPose 仓库中的完整训练配置、数据集定义与底层源码,系统讲解如何基于 HRNetv2-W18 骨干网络在 COCO-WholeBody-Face 68 点人脸数据集上完成 2D 人脸关键点检测任务的配置、训练与评测。读完本文,你将掌握该模型从数据组织、热图编解码、模型组装到 NME 指标评估的完整技术链路,并能够直接复现或改造这套配置。

一、任务与背景:COCO-WholeBody-Face 人脸关键点检测

COCO-WholeBody 是《Whole-Body Human Pose Estimation in the Wild》(ECCV'2020) 提出的全身人体姿态估计数据集,其在 COCO 数据集的基础上额外标注了人脸、手部与脚部的关键点。其中COCO-WholeBody-Face子集专门用于人脸关键点定位,遵循68 点人脸标注规则(68 points mark-up)。

在 MMPose 中,该数据集的元信息由 configs/base/datasets/coco_wholebody_face.py 定义,具体体现在:

  • 68 个关键点:索引 0~67,命名规范为face-0face-67
  • 左右对称关键点配对:每个关键点通过swap字段声明水平翻转后的对应关系,例如face-0 ↔ face-16face-17 ↔ face-26face-36 ↔ face-45等。RandomFlip数据增强正是依赖该信息在翻转后交换左右侧关键点的标签;
  • 关键点权重与 σ 值joint_weights全部为1.sigmas给出每个关键点用于 OKS 评估的归一化标准差,数值越小代表该关键点定位精度要求越严苛(如眼角、鼻尖区域的关键点 σ 值普遍更小)。

对应的数据集加载器为CocoWholeBodyFaceDataset(源码见 mmpose/datasets/datasets/face/coco_wholebody_face_dataset.py),其parse_data_info方法的核心逻辑包括:

  1. 实例过滤:当ann['face_valid']为假,或ann['face_kpts']的最大值不大于 0(即人脸关键点全部无效)时,直接丢弃该实例;
  2. 人脸框提取:从ann['face_box'](格式为xywh)解析出人脸 bbox,并裁剪到图像边界内,最终转换为[1, 4]x1, y1, x2, y2格式;
  3. 关键点提取:将ann['face_kpts']重塑为[1, K, 3],前两维为坐标、第三维为可见性标志,keypoints_visiblemin(1, vis)得到二值可见掩码。

训练与验证分别使用annotations/coco_wholebody_train_v1.0.jsonannotations/coco_wholebody_val_v1.0.json标注文件,图片分别位于train2017/val2017/目录下,data_root统一为data/coco/

二、模型卡片速览:官方基准结果

模型卡片 hrnetv2_coco_wholebody_face.md 在 COCO-WholeBody-Face 验证集上给出了该配置的官方结果:

模型架构输入尺寸NME(越低越好)配置文件权重与日志
pose_hrnetv2_w18256×2560.0569td-hm_hrnetv2-w18_8xb32-60e_coco-wholebody-face-256x256.py见模型卡片中的 ckpt 与 log 链接

其中NME(Normalized Mean Error,归一化平均误差)是人脸关键点任务的标准评测指标,数值越低代表关键点定位越精准。0.0569 的 NME 意味着平均定位误差约为双眼外眼角间距(即关键点 36 与 45 之间的距离)的 5.69%。模型卡片中还提供了该论文与数据集的 BibTeX 引用条目,可用于学术引用:

  • HRNetv2Deep High-Resolution Representation Learning for Visual Recognition(TPAMI'2019);
  • COCO-WholeBodyWhole-Body Human Pose Estimation in the Wild(ECCV'2020)。

三、完整配置逐段拆解

本节逐段解析 td-hm_hrnetv2-w18_8xb32-60e_coco-wholebody-face-256x256.py 这份官方训练配置,它遵循 MMPose 的配置继承机制,头部通过_base_引用../../../_base_/default_runtime.py

3.1 训练策略:60 个 epoch 与自动学习率缩放

train_cfg = dict(max_epochs=60, val_interval=1) optim_wrapper = dict(optimizer=dict( type='Adam', lr=2e-3, )) param_scheduler = [ dict( type='LinearLR', begin=0, end=500, start_factor=0.001, by_epoch=False), # warm-up dict( type='MultiStepLR', begin=0, end=210, milestones=[40, 55], gamma=0.1, by_epoch=True) ] auto_scale_lr = dict(base_batch_size=256) default_hooks = dict(checkpoint=dict(save_best='NME', rule='less', interval=1))

要点说明:

  • 优化器:使用Adam,初始学习率2e-3
  • 学习率调度:前 500 次迭代执行LinearLR线性 warm-up(起始系数 0.001),随后在 epoch 40 与 55 处按MultiStepLRgamma=0.1衰减学习率;
  • 自动学习率缩放auto_scale_lr声明基准 batch size 为 256。实际训练中 MMPose 会依据真实 batch size 与基准值的比例线性调整学习率,保证更换 batch size 后收敛行为基本一致;
  • 检查点保存save_best='NME', rule='less'表示以验证集 NME 最小为准则保存最优权重,且每个 epoch 保存一次 checkpoint;
  • 值得注意的是,配置文件中的end=210MultiStepLR调度器的终止步数(内部沿用原 repo 的写法),实际训练轮次由max_epochs=60控制,milestones 在 60 epoch 内均会触发。

3.2 编解码器:MSRAHeatmap

codec = dict( type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)

codec定义了关键点与热图之间的编解码方式,其实现位于 mmpose/codecs/msra_heatmap.py:

  • encode(训练时生成标签):将 256×256 输入图像空间中的关键点坐标除以scale_factor(即input_size / heatmap_size,此处为 4)映射到 64×64 热图空间,再以sigma=2生成高斯热图,同时输出keypoint_weights权重矩阵。该方法源自论文Simple Baselines for Human Pose Estimation and Tracking(Xiao et al., 2018);
  • decode(推理时解码坐标):通过get_heatmap_maximum求热图最大值位置作为粗定位,再调用refine_keypoints进行亚像素精度细化,最后乘回scale_factor还原到原图坐标;
  • 可扩展项:该编解码器还支持unbiased=True(DarkPose 无偏编解码)与blur_kernel_size参数,用于进一步提升定位精度,本配置未启用。

3.3 模型结构:HRNet 骨干 + 特征融合 + 热图头

model = dict( type='TopdownPoseEstimator', data_preprocessor=dict( type='PoseDataPreprocessor', mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], bgr_to_rgb=True), 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=(18, 36)), stage3=dict( num_modules=4, num_branches=3, block='BASIC', num_blocks=(4, 4, 4), num_channels=(18, 36, 72)), stage4=dict( num_modules=3, num_branches=4, block='BASIC', num_blocks=(4, 4, 4, 4), num_channels=(18, 36, 72, 144), multiscale_output=True), upsample=dict(mode='bilinear', align_corners=False)), init_cfg=dict( type='Pretrained', checkpoint='open-mmlab://msra/hrnetv2_w18')), neck=dict( type='FeatureMapProcessor', concat=True, ), head=dict( type='HeatmapHead', in_channels=270, out_channels=68, deconv_out_channels=None, loss=dict(type='KeypointMSELoss', use_target_weight=True), conv_out_channels=(270, ), conv_kernel_sizes=(1, ), decoder=codec), test_cfg=dict( flip_test=True, flip_mode='heatmap', shift_heatmap=True, ))

这段配置是整套系统的核心,逐项说明如下:

  • 估计器TopdownPoseEstimator是 MMPose 中「自顶向下」(top-down)姿态估计的统一封装,先检测人(脸)再估计关键点;
  • 数据预处理器PoseDataPreprocessor采用 ImageNet 的均值/标准差对输入归一化,bgr_to_rgb=True适配 OpenCV 读图通道顺序;
  • 骨干网络 HRNet-W18:四阶段高分辨率网络。W18 的含义体现在 stage2~stage4 各分支通道数为 (18, 36, 72, 144)。stage4 开启multiscale_output=True,即输出四个分辨率分支的特征;init_cfg加载在 ImageNet 上预训练的hrnetv2_w18权重;
  • 颈部特征融合FeatureMapProcessor(源码见 mmpose/models/necks/fmap_proc_neck.py)在concat=True时,将 HRNet 输出的多分辨率特征统一缩放到同一尺寸后沿通道维拼接,形成 18+36+72+144 =270通道的特征,这正对应head.in_channels=270
  • 热图回归头HeatmapHead以 1×1 卷积将 270 通道特征映射为 68 张热图(对应 68 个关键点),损失函数为KeypointMSELoss(带use_target_weight的关键点加权 MSE),decoder=codec绑定解码器用于推理阶段坐标还原;
  • 测试增强flip_test=True开启水平翻转测试(原图与翻转图的预测热图取平均),flip_mode='heatmap'表示在热图层面融合,shift_heatmap=True补偿翻转带来的亚像素偏移。

3.4 数据流水线(pipeline)

train_pipeline = [ dict(type='LoadImage'), dict(type='GetBBoxCenterScale'), dict(type='RandomFlip', direction='horizontal'), dict( type='RandomBBoxTransform', rotate_factor=60, scale_factor=(0.75, 1.25)), dict(type='TopdownAffine', input_size=codec['input_size']), dict(type='GenerateTarget', encoder=codec), dict(type='PackPoseInputs') ] val_pipeline = [ dict(type='LoadImage'), dict(type='GetBBoxCenterScale'), dict(type='TopdownAffine', input_size=codec['input_size']), dict(type='PackPoseInputs') ]

训练阶段的增强策略为:

  • RandomFlip水平随机翻转,并利用数据集元信息中的swap字段交换左右侧关键点;
  • RandomBBoxTransform对 bbox 做随机扰动:旋转幅度 ±60°,尺度缩放因子在 0.75~1.25 之间;
  • TopdownAffine依据扰动后的 bbox 将人脸区域仿射变换到 256×256 输入尺寸;
  • GenerateTarget调用codec.encode生成高斯热图标签。

验证与测试阶段则不使用任何随机增强,仅做仿射归一化,保证评测可复现。

3.5 数据加载器与评估器

train_dataloader = dict( batch_size=32, num_workers=2, persistent_workers=True, sampler=dict(type='DefaultSampler', shuffle=True), dataset=dict( type=dataset_type, # CocoWholeBodyFaceDataset data_root=data_root, # data/coco/ data_mode=data_mode, # topdown ann_file='annotations/coco_wholebody_train_v1.0.json', data_prefix=dict(img='train2017/'), pipeline=train_pipeline, )) val_evaluator = dict( type='NME', norm_mode='keypoint_distance', ) test_evaluator = val_evaluator

配置名中的8xb32即表示 8 张 GPU × 每卡 batch size 32(与auto_scale_lr的 256 基准 batch size 一致)。验证与测试共享同一套评估器。

四、NME 评估指标的底层原理

人脸关键点评测使用的是NME指标类(源码见 mmpose/evaluation/metrics/keypoint_2d_metrics.py),它支持两种归一化模式:

  1. use_norm_item:使用标注中的某个字段(如bbox_size)作为归一化因子;
  2. keypoint_distance(本配置采用):使用一对关键点之间的距离作为归一化因子,通常取两眼外眼角之间的距离,以消除人脸尺度差异对误差的影响。

NME类内置了DEFAULT_KEYPOINT_INDICES映射表,其中coco_wholebody_face: [36, 45]正是左右外眼角关键点的索引。因此本配置中无需显式指定keypoint_indices,评估器会自动依据数据集名称从映射表中取出[36, 45],计算二者平均距离后,将每个关键点的平均定位误差除以该距离,最终得到 NME 值。这一细节解释了为何 configs/base/datasets/coco_wholebody_face.py 中 36 号与 45 号关键点恰好构成swap配对(face-36 ↔ face-45):它们既是几何对称点,又是评估归一化的基准锚点。

从评估实现看,NME.process收集预测关键点、真值关键点与可见性掩码;compute_metrics依据掩码过滤不可见关键点后调用keypoint_nme计算归一化误差,并以metrics['NME']输出。

五、训练与测试:如何复现与验证

在准备好数据(将 COCO-WholeBody 标注文件与图片按data/coco/目录结构摆放)后,可直接使用仓库提供的工具脚本复现训练:

# 单机多卡训练 bash tools/dist_train.sh \ configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_hrnetv2-w18_8xb32-60e_coco-wholebody-face-256x256.py \ 8 # 单卡训练 python tools/train.py \ configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_hrnetv2-w18_8xb32-60e_coco-wholebody-face-256x256.py

训练结束后,使用tools/test.py加载官方或自训权重在验证集上复现 NME 指标:

python tools/test.py \ configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_hrnetv2-w18_8xb32-60e_coco-wholebody-face-256x256.py \ <checkpoint路径> --out <结果文件>

训练与测试的通用参数细节可参考 docs/zh_cn/user_guides/train_and_test.md(英文版见 docs/en/user_guides/train_and_test.md)。此外,仓库还提供了一整套可视化与推理工具:可使用 demo/topdown_demo_with_mmdet.py 配合检测器完成端到端的人脸关键点演示,或参考 docs/zh_cn/user_guides/inference.md 使用高层推理接口MMPoseInferencer加载该模型权重直接推理。

六、扩展与改造建议

基于本配置,可以从以下几个方向进行低成本改造:

  1. 更换输入分辨率:将codec.input_size与流水线中的仿射尺寸同步调整为 224×224 或 384×384,精度与速度将随之此消彼长,同时建议同步调整heatmap_size保持 4 倍下采样比例;
  2. 启用 DarkPose 精修:在codec中加入unbiased=True,配合KeypointMSELoss与解码阶段的refine_keypoints_dark,通常在 NME 上可获得进一步收益;
  3. 更换骨干:将backbone替换为 MMPose 内置的其他骨干(如CSPNeXtLiteHRNet等),FeatureMapProcessor的拼接通道数与head.in_channels需按新骨干输出通道重新计算;
  4. 调整训练超参:修改train_cfg.max_epochsparam_scheduler.milestones或优化器学习率时,注意auto_scale_lr.base_batch_size应与实际总 batch size 保持一致,否则学习率缩放会偏离预期。

如需查看更多人脸关键点模型的横向对比,可查阅 configs/face_2d_keypoint/README.md 与 docs/zh_cn/dataset_zoo/2d_face_keypoint.md(英文版 docs/en/dataset_zoo/2d_face_keypoint.md),其中包含基于 300W、WFLW、AFLW、COFW 等数据集的多模型评测总览。

七、小结

本文以 HRNetv2-W18 在 COCO-WholeBody-Face 上的模型卡片为线索,完整覆盖了:数据集定义与 68 点标注规范(configs/base/datasets/coco_wholebody_face.py)、数据集加载器的实例解析逻辑(coco_wholebody_face_dataset.py)、高斯热图编解码原理(msra_heatmap.py)、HRNet 多分支特征融合与热图头结构、NME 指标的眼距归一化机制(keypoint_2d_metrics.py),以及训练测试的完整命令行流程。该配置在验证集上取得 0.0569 的 NME,可作为人脸关键点任务中「高分辨率表示 + 热图回归」这一经典范式的可靠基线与迁移起点。

【免费下载链接】mmposeOpenMMLab Pose Estimation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmpose

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 5:40:23

小程序接口签名机制逆向分析:从抓包到算法还原

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/17 5:39:59

本地知识库落地实战:FAISS+Qwen2.5构建办公级智能文档工作流

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/17 5:38:42

STM32C5+LSM6DSV320X陀螺仪轮询读取实战:寄存器配置与数据解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/17 5:38:42

DeepSeek接入Excel实操:公式生成、VBA自动化与大数据处理

简介&#xff1a;一份聚焦DeepSeek与Excel融合应用的办公效率提升图文教程&#xff0c;面向具备一定Excel基础、频繁处理数据分析和报表制作的职场用户&#xff0c;解决数据清洗耗时、公式编写复杂、图表呈现不直观等高频痛点。文档从Transformer架构的核心原理切入&#xff0c…

作者头像 李华