ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

MMPose 人脸关键点检测实战:Hourglass 堆叠沙漏网络在 COCO-WholeBody-Face 数据集上的训练与评测

MMPose 人脸关键点检测实战:Hourglass 堆叠沙漏网络在 COCO-WholeBody-Face 数据集上的训练与评测 MMPose 人脸关键点检测实战Hourglass 堆叠沙漏网络在 COCO-WholeBody-Face 数据集上的训练与评测【免费下载链接】mmposeOpenMMLab Pose Estimation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmpose本文以 MMPose 仓库中 td-hm_hourglass52_8xb32-60e_coco-wholebody-face-256x256.py 这一官方配置为线索系统讲解如何用 Stacked Hourglass堆叠沙漏网络完成 COCO-WholeBody-Face 人脸 68 点关键点检测从配置文件的逐项拆解、数据流水线与编解码器原理到 NME 评测指标、训练与测试命令一应俱全。读完本文你将能够独立复现该模型在验证集上 NME 0.0587 的结果并掌握基于 MMPose 自顶向下Top-Down人脸关键点任务的完整开发链路。一、任务背景COCO-WholeBody-Face 上的 68 点人脸关键点检测1.1 数据集COCO-WholeBody-FaceCOCO-WholeBodyECCV2020论文Whole-Body Human Pose Estimation in the Wild在原始 COCO 数据集基础上补充了人体全身各部位的密集标注其中人脸关键点采用 68 点标注协议。MMPose 从中抽取面部标注构成了独立的COCO-WholeBody-Face人脸关键点数据集。在仓库中该数据集的元信息METAINFO由 coco_wholebody_face.py 定义包括dataset_name、68 个关键点的名称face_kpt_names、骨骼连接关系以及关键点颜色等信息数据集的加载逻辑实现在 coco_wholebody_face_dataset.py 中DATASETS.register_module() class CocoWholeBodyFaceDataset(BaseCocoStyleDataset): METAINFO: dict dict( from_fileconfigs/_base_/datasets/coco_wholebody_face.py)从源码的parse_data_info可以看到几个对训练影响关键的处理细节通过face_valid标志过滤掉无有效人脸标注的实例从face_box读取人脸框xywh 格式并裁剪到图像边界内转换成[1, 4]的 xyxy 格式 bbox将face_kpts的(x, y, visible)三元组拆分为关键点坐标keypoints与可见性keypoints_visible可见性阈值取min(1, v)即只要标注为非 0 就视为可见。这些细节决定了本配置中ann_file、data_prefix等字段的写法也是理解后续数据管线的前提。1.2 算法HourglassECCV2016Hourglass 网络由 Newell 等人于 2016 年提出论文Stacked Hourglass Networks for Human Pose Estimation其核心思想是通过重复的下采样-上采样沙漏结构同时捕获人脸的全局上下文信息与局部精细特征先逐步池化降低分辨率以获取整体语义再通过上采样恢复空间分辨率并利用跳跃连接skip connection将各尺度的特征相加从而实现对关键点的精确定位。堆叠多个沙漏模块Stacked并对每个阶段的输出分别计算损失可以进一步细化预测。在本配置中使用的num_stacks1对应论文中的Hourglass-52单沙漏、52 层而num_stacks2则是 Hourglass-104。二、配置全景从零拆解官方训练配置官方配置 td-hm_hourglass52_8xb32-60e_coco-wholebody-face-256x256.py 的名字已经透露了关键信息td-hmTop-Down Heatmap 自顶向下热图方法、hourglass52骨干网络、8xb328 卡 × 每卡 32 样本共 256 批大小、60e60 个 epoch、输入尺寸256x256。下面逐段拆解。2.1 运行时与优化器设置_base_ [../../../_base_/default_runtime.py] # runtime train_cfg dict(max_epochs60, val_interval1) # optimizer optim_wrapper dict(optimizerdict( typeAdam, lr2e-3, ))配置以 default_runtime.py 为基础继承其中的 hooks、可视化后端、日志处理器、环境配置等默认项再覆盖训练轮数与优化器train_cfg训练 60 个 epoch每个 epoch 结束后执行一次验证val_interval1optimizer采用Adam优化器初始学习率lr2e-3未额外指定 weight decay因此使用默认值。default_runtime.py 中还内置了BadCaseAnalysisHook默认关闭enableFalse、SyncBuffersHook等组件以及cudnn_benchmarkFalse、dist_cfgdict(backendnccl)等分布式训练环境配置。2.2 学习率调度线性热身 多步衰减# learning policy param_scheduler [ dict( typeLinearLR, begin0, end500, start_factor0.001, by_epochFalse), # warm-up dict( typeMultiStepLR, begin0, end210, milestones[40, 55], gamma0.1, by_epochTrue) ]学习率采用两段式调度线性热身warm-up前 500 个 iteration 内学习率从初始值的start_factor0.001即 2e-6线性攀升到 2e-3by_epochFalse表示按 iteration 计多步衰减MultiStepLR在第 40 与第 55 个 epoch学习率按gamma0.1衰减即 2e-3 → 2e-4 → 2e-5。2.3 批大小自适应缩放学习率# automatically scaling LR based on the actual training batch size auto_scale_lr dict(base_batch_size256)auto_scale_lr是 MMPose/MMEngine 提供的学习率自动缩放机制base_batch_size256表示学习率 2e-3 是在总批大小 2568 卡 × 32下调参得到的当实际训练的批大小改变时框架会依据批大小比例自动缩放学习率保证训练行为的等价性。2.4 模型结构HourglassNet 骨干 CPMHead 头部# model settings model dict( typeTopdownPoseEstimator, data_preprocessordict( typePoseDataPreprocessor, mean[123.675, 116.28, 103.53], std[58.395, 57.12, 57.375], bgr_to_rgbTrue), backbonedict( typeHourglassNet, num_stacks1, ), headdict( typeCPMHead, in_channels256, out_channels68, num_stages1, deconv_out_channelsNone, lossdict(typeKeypointMSELoss, use_target_weightTrue), decodercodec), test_cfgdict( flip_testTrue, flip_modeheatmap, shift_heatmapTrue, ))这是整个配置的核心包含四个层次TopdownPoseEstimator自顶向下姿态估计器即先由检测器给出人脸框再对框内区域单人地预测关键点本配置不包含检测器需要外部人脸检测器配合见下文推理部分PoseDataPreprocessor数据预处理器使用 ImageNet 统计的mean/std做标准化bgr_to_rgbTrue说明输入图像按 BGR 读入后需转为 RGBHourglassNet骨干网络仅指定num_stacks1其余参数downsample_times5、stage_channels、stage_blocks等使用源码默认值CPMHead多阶段热图头源自 Convolutional Pose Machines为 Stacked Hourglass 配套使用in_channels256对应骨干输出特征通道数out_channels68对应 68 个面部关键点num_stages1与num_stacks1对应deconv_out_channelsNone表示该阶段不额外堆叠反卷积上采样层损失函数KeypointMSELoss关键点 MSE 损失use_target_weightTrue表示按关键点可见性加权test_cfg测试时启用水平翻转测试TTAflip_modeheatmap表示对热图翻转并shift_heatmapTrue做像素偏移补偿因为翻转前后热图坐标存在半像素错位。2.5 编解码器MSRAHeatmap# codec settings codec dict( typeMSRAHeatmap, input_size(256, 256), heatmap_size(64, 64), sigma2)MSRAHeatmap是经典的热图编解码器源自Simple Baselines for Human Pose EstimationXiao et al. 2018其核心参数为参数取值含义input_size(256, 256)网络输入图像尺寸heatmap_size(64, 64)生成的热图尺寸为输入的 1/4sigma2高斯热图的标准差像素决定每个关键点峰的弥散范围unbiasedFalse默认是否使用 DarkPose 无偏编码本配置未开启从 msra_heatmap.py 源码可见其编码过程关键点坐标除以scale_factor input_size / heatmap_size即 4缩放到热图坐标系后通过generate_gaussian_heatmaps生成(K, H, W)的高斯热图K68 个关键点HW64并返回对应的keypoint_weights。解码时则对热图取最大值位置get_heatmap_maximum得到整数像素坐标再用refine_keypoints结合周围像素做亚像素精度的坐标细化最后乘以scale_factor还原到输入图像坐标系。MSRAHeatmap支持unbiasedTrue切换到 DarkPose 方案对应仓库中同目录下的 td-hm_hrnetv2-w18_dark-8xb32-60e_coco-wholebody-face-256x256.py 配置可在不换模型结构的前提下进一步提升精度。2.6 数据流水线与 DataLoader# base dataset settings dataset_type CocoWholeBodyFaceDataset data_mode topdown data_root data/coco/ # pipelines train_pipeline [ dict(typeLoadImage), dict(typeGetBBoxCenterScale), dict(typeRandomFlip, directionhorizontal), dict( typeRandomBBoxTransform, rotate_factor60, scale_factor(0.75, 1.25)), 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) ]训练流水线依次完成加载图像 → 由 bbox 计算中心点与尺度 → 以 0.5 概率水平翻转 → 随机 bbox 变换旋转 ±60°、尺度缩放 0.75~1.25 倍→ 仿射变换裁剪到 256×256 → 调用MSRAHeatmap编解码器生成高斯热图标签 → 打包为模型输入。验证流水线则去掉所有随机增强只保留仿射对齐。train_dataloader dict( batch_size32, num_workers2, persistent_workersTrue, samplerdict(typeDefaultSampler, shuffleTrue), datasetdict( typedataset_type, data_rootdata_root, data_modedata_mode, ann_fileannotations/coco_wholebody_train_v1.0.json, data_prefixdict(imgtrain2017/), pipelinetrain_pipeline, )) val_dataloader dict( batch_size32, num_workers2, persistent_workersTrue, drop_lastFalse, samplerdict(typeDefaultSampler, shuffleFalse, round_upFalse), datasetdict( typedataset_type, data_rootdata_root, data_modedata_mode, ann_fileannotations/coco_wholebody_val_v1.0.json, data_prefixdict(imgval2017/), test_modeTrue, pipelineval_pipeline, )) test_dataloader val_dataloader数据组织要点训练集与验证集分别使用coco_wholebody_train_v1.0.json与coco_wholebody_val_v1.0.json标注文件图片分别位于data/coco/train2017/与data/coco/val2017/data_rootdata/coco/下训练集shuffleTrue随机打乱验证集shuffleFalse, round_upFalse且test_modeTrue表示进入评测模式test_dataloader val_dataloader直接复用验证集数据8 卡训练时单卡 batch_size32总批大小 256与auto_scale_lr的base_batch_size一致。2.7 评测配置NME 指标# evaluators val_evaluator dict( typeNME, norm_modekeypoint_distance, ) test_evaluator val_evaluator人脸关键点领域使用NMENormalized Mean Error归一化平均误差作为标准评测指标。从 keypoint_2d_metrics.py 中NME类的源码可以看到其两种归一化模式use_norm_item使用数据信息中某一项如bbox_size作为归一化因子keypoint_distance使用一对指定关键点之间的距离作为归一化因子。本配置使用后者。源码中DEFAULT_KEYPOINT_INDICES为coco_wholebody_face定义了默认关键点索引对[36, 45]——即左右眼外眼角right-most和left-mosteye keypoints。NME 即所有关键点的平均欧氏距离除以双眼间距值越小精度越高这一设计使人脸尺寸差异不会直接影响误差读数便于跨尺度公平比较。三、源码级原理骨干网络与检测头的内部实现3.1 HourglassNet递归构建的沙漏模块骨干网络实现在 hourglass.py 中。HourglassModule采用递归定义构建沙漏结构class HourglassModule(BaseModule): def __init__(self, depth, stage_channels, stage_blocks, ...): self.up1 ResLayer(BasicBlock, cur_block, cur_channel, cur_channel, ...) # 保持分辨率分支 self.low1 ResLayer(..., stride2, ...) # 下采样分支 if self.depth 1: self.low2 HourglassModule(depth - 1, stage_channels[1:], stage_blocks[1:]) # 递归 else: self.low2 ResLayer(...) self.low3 ResLayer(..., downsample_firstFalse) # 上采样前的特征处理 self.up2 nn.Upsample(scale_factor2) # 最近邻上采样 def forward(self, x): up1 self.up1(x) low1 self.low1(x) low2 self.low2(low1) low3 self.low3(low2) up2 self.up2(low3) return up1 up2 # 跳跃连接相加关键设计一目了然up1与up2的逐元素相加实现跳跃连接使高分辨率细节信息绕过深层瓶颈直接传递给输出low1用 stride2 卷积下采样up2用nn.Upsample恢复分辨率形成完整的先降后升沙漏。HourglassNet的默认结构参数为downsample_times5每个沙漏模块内下采样 5 次num_stacks2默认本配置改为 1即 Hourglass-52stage_channels(256, 256, 384, 384, 384, 512)、stage_blocks(2, 2, 2, 2, 2, 4)网络先经 stem7×7 卷积 残差层两次 stride2 下采样提取初始特征再进入沙漏模块多栈时通过 1×1 卷积与中间残差层inters将前一栈输出反馈到下一栈实现多阶段级联细化。3.2 CPMHead多阶段热图头与翻转测试检测头实现在 cpm_head.py 中CPMHead支持多阶段输出。前向过程为对每个阶段的特征依次经过反卷积层multi_deconv_layers本配置deconv_out_channelsNone时退化为nn.Identity与 1×1 卷积multi_final_layers输出(B, 68, 64, 64)的热图。两个重要实现细节值得注意多阶段损失loss方法对每个阶段的热图分别计算 MSE 损失并累加本配置只有 1 个阶段因此loss_kpt只计算一次同时通过pose_pck_accuracy计算平均关键点准确率acc_pose用于训练日志监控翻转测试TTApredict方法中当test_cfg[flip_test]True时对原始图像与水平翻转图像分别前向将翻转热图通过flip_heatmaps含flip_indices关键点索引重排与shift_heatmap半像素偏移校正后与原热图求平均再统一解码出关键点坐标。这是验证集 NME 0.0587 能稳定复现的关键设置之一。四、模型基准与结果官方在 COCO-WholeBody-Face 验证集上的评测结果如下来源hourglass_coco_wholebody_face.md 及配套 hourglass_coco_wholebody_face.yml架构输入尺寸NME配置文件pose_hourglass_52256×2560.0587td-hm_hourglass52_8xb32-60e_coco-wholebody-face-256x256.py模型权重checkpoint与训练日志的官方下载地址记录在同目录的 hourglass_coco_wholebody_face.yml 的Weights字段中权重由 OpenMMLab 官方发布hourglass52_coco_wholebody_face_256x256-6994cf2e_20210909.pth可直接用于离线推理或继续训练。作为对照该目录下还提供了HRNet-w18含 DarkPose 变体、ResNet-50、SCNet-50、MobileNetV2等同任务配置见 coco_wholebody_face 目录便于在精度与速度之间横向权衡。五、数据准备与训练测试5.1 数据集准备按data_rootdata/coco/的约定需要将 COCO-WholeBody 数据集组织为如下目录结构data/coco/ ├── annotations/ │ ├── coco_wholebody_train_v1.0.json │ └── coco_wholebody_val_v1.0.json ├── train2017/ └── val2017/完整的数据集下载与格式说明请参考 prepare_datasets.md英文版见 prepare_datasets.md。5.2 训练使用仓库根目录下的 train.py 启动训练# 单卡训练 python tools/train.py configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_hourglass52_8xb32-60e_coco-wholebody-face-256x256.py # 多卡8 卡分布式训练 bash tools/dist_train.sh configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_hourglass52_8xb32-60e_coco-wholebody-face-256x256.py 8关键行为说明训练过程中每 1 个 epoch 在验证集上评测一次val_interval1并使用default_hooks.checkpoint的save_bestNME, ruleless设置见配置第 30 行保存 NME 最低的模型为最佳权重若实际可用 GPU 数量导致总批大小不是 256建议开启--auto-scale-lrtrain.py 支持该参数触发auto_scale_lr的学习率自动缩放训练配置中default_runtime.py的CheckpointHook默认interval10本配置覆盖为interval1即每个 epoch 都会保存 checkpoint若以较小的 GPU 显存训练可下调batch_size并配合--auto-scale-lr保持训练动力学近似。5.3 测试与指标复现使用 test.py 在验证集上评测python tools/test.py configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_hourglass52_8xb32-60e_coco-wholebody-face-256x256.py \ checkpoint.pth --out 输出结果文件评测过程将启用配置中的翻转测试flip_testTrue最终输出NME指标。若使用官方发布的预训练权重可复现 NME ≈ 0.0587 的基准结果。5.4 端到端推理由于自顶向下方法需要先定位人脸框实际部署通常配合人脸检测器一起使用。MMPose 提供了 topdown_demo_with_mmdet.py 演示脚本将 MMDetection 的人脸检测器与本模型串联完成检测 关键点端到端推理此外 inferencer_demo.py 展示了基于MMPoseInferencer的统一推理接口用法更多单图/多图/视频推理示例可参考 2d_face_demo.md 与 2d_face_demo.md。六、结语与进一步探索通过本配置我们完整走通了 MMPose 中Hourglass 骨干 CPMHead 热图头 MSRAHeatmap 编解码 NME 评测这一经典人脸关键点方案的每一个环节CocoWholeBodyFaceDataset负责数据解析与 68 点标注加载HourglassNet用递归沙漏与跳跃连接捕获多尺度人脸结构CPMHead输出 64×64 高斯热图并支持翻转 TTANME以双眼间距归一化误差实现尺度无关的精度度量。这一套组件的组合方式对其他数据集如 wflw、aflw、300w同样适用只需替换数据集与关键点元信息即可迁移。若想进一步理解框架层面的编排机制可以继续阅读 guide_to_framework.md英文版见 guide_to_framework.md如果想对比更现代的人脸关键点方案如基于 SimCC 表示与 RTMPose 的轻量级模型可以浏览 face_2d_keypoint/rtmpose 下的配置。【免费下载链接】mmposeOpenMMLab Pose Estimation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmpose创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表