news 2026/9/17 2:58:05

MMDetection 之外的 29 点人脸关键点定位:MMPose 中 HRNetv2 在 COFW 数据集上的完整配置与复现指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MMDetection 之外的 29 点人脸关键点定位:MMPose 中 HRNetv2 在 COFW 数据集上的完整配置与复现指南

MMDetection 之外的 29 点人脸关键点定位:MMPose 中 HRNetv2 在 COFW 数据集上的完整配置与复现指南

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

导读

本文以 MMPose 仓库中的 configs/face_2d_keypoint/topdown_heatmap/cofw/hrnetv2_cofw.md 模型页为核心,系统讲解基于 HRNetv2 骨干网络在 COFW 人脸关键点数据集上的 top-down 热图回归方案。你将了解到该模型页记录的官方评测结果(NME 3.48)、完整配置文件 td-hm_hrnetv2-w18_8xb64-60e_cofw-256x256.py 的每一处参数含义、COFW 数据集的组织与转换流程,以及从数据准备到训练、测试、推理的完整实操路径。

模型页概览:HRNetv2 × COFW 的结果与引用信息

hrnetv2_cofw.md是一个典型的 Model Zoo 结果页,它记录了该模型在 COFW 测试集上的官方成绩,并附带了算法与数据集的 BibTeX 引用,方便学术使用。

算法与数据集出处

  • HRNetv2(TPAMI'2019):《Deep High-Resolution Representation Learning for Visual Recognition》,作者为 Jingdong Wang、Ke Sun、Tianheng Cheng 等。HRNet 的核心思想是全程保持高分辨率特征表示,并通过并行多分辨率子网不断交换信息,这一设计在 2D 人体/人脸关键点任务上带来了明显精度提升。本仓库中对应实现位于 mmpose/models/backbones/hrnet.py。
  • COFW(ICCV'2013):《Robust face landmark estimation under occlusion》,作者为 Burgos-Artizzu、Perona、Dollár。COFW 数据集以其"遮挡下的鲁棒人脸关键点估计"著称,共标注 29 个关键点,是评估人脸关键点模型在遮挡场景下鲁棒性的重要基准。其数据集元信息定义在 configs/base/datasets/cofw.py,对应的加载实现为 mmpose/datasets/datasets/face/cofw_dataset.py 中的COFWDataset

官方评测结果

模型页给出的官方结果表如下(模型仅在 COFW 训练集上训练):

ArchInput SizeNMEckptlog
pose_hrnetv2_w18256x2563.48ckptlog

这一结果同时被记录在配套的 hrnetv2_cofw.yml 元数据文件中:任务为 Face 2D Keypoint,训练数据为 COFW,权重文件为hrnetv2_w18_cofw_256x256-49243ab8_20211019.pth

说明:本文不展开外部下载链接的细节,ckpt 与 log 的实际获取方式请以模型页中的链接为准;权重文件通常由tools/misc/pth_transfer.py等工具配合init_cfgPretrained方式载入。

配置逐段解析:td-hm_hrnetv2-w18_8xb64-60e_cofw-256x256.py

配置文件命名遵循 MMPose 的语义化规范:td-hm(top-down heatmap 范式)、hrnetv2-w18(骨干网络为 HRNetV2-W18)、8xb64(8 卡 × batch size 64)、60e(60 个 epoch)、cofw-256x256(数据集与输入尺寸)。下面按模块拆解其每一部分。

训练配置与优化器

_base_ = ['../../../_base_/default_runtime.py'] # runtime train_cfg = dict(max_epochs=60, val_interval=1) # optimizer optim_wrapper = dict(optimizer=dict(type='Adam', lr=2e-3)) # learning policy param_scheduler = [ dict(type='LinearLR', begin=0, end=500, start_factor=0.001, by_epoch=False), # warm-up dict(type='MultiStepLR', begin=0, end=50, milestones=[40, 55], gamma=0.1, by_epoch=True) ] # automatically scaling LR based on the actual training batch size auto_scale_lr = dict(base_batch_size=512)
  • 训练 60 个 epoch,每个 epoch 后做一次验证(val_interval=1)。
  • 优化器使用 Adam,初始学习率2e-3
  • 学习率策略分两段:前 500 次迭代(by_epoch=False,即按 iteration 计)用LinearLR做 warm-up,从start_factor=0.001线性爬升;之后按 epoch 采用MultiStepLR,在第 40、55 个 epoch 各衰减为原来的 0.1(gamma=0.1)。
  • auto_scale_lr声明基准 batch size 为 512,实际训练 batch size 与之不同时,MMPose 会自动按比例缩放学习率。

编解码器:MSRAHeatmap

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

MSRAHeatmap来自论文《Simple Baselines for Human Pose Estimation and Tracking》(Xiao et al., 2018),其实现位于 mmpose/codecs/msra_heatmap.py。编码阶段将 256×256 输入图像中的关键点坐标按scale_factor = input_size / heatmap_size = 4缩放,并生成 64×64 分辨率、标准差sigma=1.5的高斯热图;解码阶段则通过get_heatmap_maximum取热图最大值位置,再配合refine_keypoints做亚像素细化,最后乘以scale_factor还原到原图坐标。该 codec 还支持unbiased=True开启 DarkPose 无偏编码(见generate_unbiased_gaussian_heatmaps),本配置未开启。

模型结构:TopdownPoseEstimator

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=29, deconv_out_channels=None, conv_out_channels=(270, ), conv_kernel_sizes=(1, ), loss=dict(type='KeypointMSELoss', use_target_weight=True), decoder=codec), test_cfg=dict(flip_test=True, flip_mode='heatmap', shift_heatmap=True))
  • 骨干:HRNet-W18,四个 stage 分别输出 1/2/3/4 条并行分支,通道数依次为 (18, 36, 72, 144);multiscale_output=True使 stage4 保留多分辨率输出,以便 neck 做特征融合。预训练权重来自open-mmlab://msra/hrnetv2_w18
  • neckFeatureMapProcessorconcat=True将 HRNet 的多尺度特征图在通道维拼接。
  • headHeatmapHeadin_channels=270恰好等于 18+36+72+144 之和;out_channels=29对应 COFW 的 29 个关键点;deconv_out_channels=None表示不采用 SimpleBaselines 式的反卷积上采样,而是用 1×1 卷积在原始热图分辨率上输出。损失为KeypointMSELoss(带use_target_weight=True的加权 MSE),配合decoder=codec完成热图到坐标的解码。
  • 测试策略flip_test=True开启水平翻转测试融合,flip_mode='heatmap'表示在热图层面融合,shift_heatmap=True补偿翻转引起的像素偏移。

数据管线与数据加载

dataset_type = 'COFWDataset' data_mode = 'topdown' data_root = 'data/cofw/'

训练管线包含LoadImageGetBBoxCenterScaleRandomFlipRandomBBoxTransformrotate_factor=60scale_factor=(0.75, 1.25),不做平移)→TopdownAffineGenerateTargetPackPoseInputs;验证管线仅包含LoadImageGetBBoxCenterScaleTopdownAffinePackPoseInputs,不引入任何随机增强。

数据加载部分:训练集 batch size 64、2 个 worker,标注文件为annotations/cofw_train.json;验证集 batch size 32,标注文件为annotations/cofw_test.jsontest_mode=Truetest_dataloader = val_dataloader。评估器使用NME指标并指定norm_mode='keypoint_distance'

指标解析:COFW 上的 NME(Normalized Mean Error)

NME度量类实现在 mmpose/evaluation/metrics/keypoint_2d_metrics.py 中。NME计算关键点的平均欧氏距离并除以一个归一化因子,支持两种归一化模式:

  • use_norm_item:使用 datainfo 中指定的归一化项(如 AFLW 的bbox_size);
  • keypoint_distance:使用数据集默认的左右眼外眼角关键点距离作为归一化因子。

COFW 的默认关键点索引在NME.DEFAULT_KEYPOINT_INDICES中定义为'cofw': [8, 9],即右、左眼最外侧关键点。模型页给出的NME 3.48即是在这一归一化约定下得到的测试精度,数值越小代表定位越准。

COFW 数据集准备:从 .mat 到 COCO 格式

COFW 数据集的原生格式为 MATLAB 的.mat文件,需要转换为 COCO 风格 JSON 后才能被COFWDataset(继承自BaseCocoStyleDataset)加载。官方数据准备流程记录在 docs/en/dataset_zoo/2d_face_keypoint.md:

  1. 下载COFW_color.zip,将COFW_train_color.matCOFW_test_color.mat放入data/cofw/目录;
  2. 在仓库根目录下运行转换脚本:
python tools/dataset_converters/parse_cofw_dataset.py
  1. 转换完成后得到data/cofw/annotations/cofw_train.jsoncofw_test.json以及data/cofw/images/下的解包图片。

转换脚本位于 tools/dataset_converters/parse_cofw_dataset.py。转换后的数据集元信息(29 个关键点、左右对称点的swap关系、关键点权重与 sigma)定义在 configs/base/datasets/cofw.py,其中joint_weights=[1.] * 29表示各点权重一致,sigmas=[]表明该数据集不使用基于 sigma 的 OKS 评估,而是以 NME 为主。

训练、测试与单图推理

单卡/多卡训练

# 单卡 python tools/train.py configs/face_2d_keypoint/topdown_heatmap/cofw/td-hm_hrnetv2-w18_8xb64-60e_cofw-256x256.py # 8 卡分布式训练 bash tools/dist_train.sh configs/face_2d_keypoint/topdown_heatmap/cofw/td-hm_hrnetv2-w18_8xb64-60e_cofw-256x256.py 8

训练过程中,default_hooks中的checkpoint被配置为save_best='NME', rule='less', interval=1,即每个 epoch 都会评估 NME 并保存最优权重(NME 越小越好)。SLURM 集群用户可参考 tools/slurm_train.sh。

测试与推理

python tools/test.py configs/face_2d_keypoint/topdown_heatmap/cofw/td-hm_hrnetv2-w18_8xb64-60e_cofw-256x256.py <checkpoint路径>

测试时会自动加载 hrnetv2_cofw.yml 中登记的权重,或指定本地权重路径。单张图片的快速推理可使用 demo/topdown_demo_with_mmdet.py(需配合检测器提供人脸框)或 demo/inferencer_demo.py(直接使用 mmpose/apis/inferencers/pose2d_inferencer.py 提供的统一推理接口)。

源码佐证:COFWDataset 与测试数据

COFWDataset在 mmpose/datasets/datasets/face/cofw_dataset.py 中定义,其 docstring 明确指出:标注采用 29 点 mark-up,论文为《Robust face landmark estimation under occlusion》(ICCV'2013),METAINFO直接从configs/_base_/datasets/cofw.py加载。这意味着只要保持_base_元信息不变,任何以from_file='configs/_base_/datasets/cofw.py'为元信息的自定义数据集都可以复用该模型配置。仓库还提供了 COFW 的测试样例数据(tests/data/cofw 下的*.json*.jpg),可用于快速验证数据管线是否正常工作。

小结

从 hrnetv2_cofw.md 出发,本文完整还原了 MMPose 中 HRNetv2-W18 在 COFW 29 点人脸关键点任务上的落地全貌:官方 NME 3.48 的结果基线、MSRAHeatmap 编解码原理、TopdownPoseEstimator各模块参数、NME 指标的归一化细节、.mat原始数据到 COCO 格式的转换流程,以及训练、测试与推理命令。无论你是要复现该基线、在其基础上调参,还是将 COFW 作为遮挡场景人脸关键点基准,都可以直接以本仓库的配置与源码作为起点。

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

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

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

工业无线遥控器串频、掉线、频繁坏?从原理到排查选型一次讲清

行吊、龙门吊、卷扬机&#xff0c;这些设备一旦配上遥控器&#xff0c;就默认了它必须"随时响应、指哪打哪"。可在实际产线上跑了几年&#xff0c;我发现工业无线遥控器从来不是装上就能省心的东西——信号串频导致误动作、操作中突然掉线、按键摇杆用了没几个月就失…

作者头像 李华
网站建设 2026/9/17 2:56:17

工业CT在固态电池内部缺陷检测中的应用与选型指南

有一次在一家中试线现场&#xff0c;我碰到一个挺典型的场景&#xff1a;一批硫化物固态电池样品走完循环测试后&#xff0c;有几只容量突然跳水&#xff0c;电压曲线明显异常。产线工程师先是做了外观检查&#xff0c;没有发现任何鼓包或破损&#xff1b;拉去做常规的X射线透射…

作者头像 李华
网站建设 2026/9/17 2:55:31

Java后端消息队列实战:RabbitMQ在分布式架构中的落地与部署

做Java后端开发这些年&#xff0c;我越来越觉得消息队列是绕不开的一块硬骨头。尤其是当你在简历上写过“熟悉分布式架构”之后&#xff0c;面试官大概率会追问&#xff1a;RabbitMQ 在你的项目里到底扮演什么角色&#xff1f;消息丢了怎么办&#xff1f;重复消费怎么解决&…

作者头像 李华
网站建设 2026/9/17 2:55:20

Claude Code 跑学生成绩管理系统:Key 用 TaoToken

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

作者头像 李华