MMPose 中 Wing Loss 的实现与应用——面向鲁棒人脸关键点定位的分段损失函数
发布时间:2026/9/17 18:25:32来源:尧图网络
MMPose 中 Wing Loss 的实现与应用——面向鲁棒人脸关键点定位的分段损失函数【免费下载链接】mmposeOpenMMLab Pose Estimation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmposeWing Loss 是 CVPR 2018 提出的一类专为人脸关键点Facial Landmark定位设计的损失函数其核心思想是在训练回归模型时对小误差与中等误差赋予更高的关注从而提升关键点定位精度。本文以仓库中的算法卡片 docs/src/papers/algorithms/wingloss.md 为骨架结合 MMPose 中WingLoss、SoftWingLoss、AdaptiveWingLoss的源码实现、WFLW 数据集上的完整训练配置与评测结果讲解该损失函数的数学定义、参数含义、配置方法以及背后的数据均衡策略读完即可在 MMPose 中复现基于 Wing Loss 的人脸关键点回归模型。论文背景为什么要关注小误差与中误差在人脸关键点定位任务中常用的损失函数包括 L2、L1 与 Smooth L1。论文对这些损失函数进行对比分析后指出基于 CNN 的定位模型训练时应当把更多注意力放在小范围与中等范围的误差上——因为经过多轮迭代后模型大部分预测误差都会落入这一区间损失函数在小误差区的梯度行为直接决定了模型的收敛精度。基于这一动机论文设计了分段piece-wise损失函数 Wing Loss在误差区间(-w, w)内将 L1 损失替换为一个修正的对数函数从而放大该区间内的误差贡献在区间之外退化为线性函数保持对大误差的稳定性。此外论文还针对训练集中大角度头部旋转large out-of-plane head rotations样本不足的问题提出了称为pose-based data balancing基于姿态的数据均衡的增强策略通过复制少数类样本并注入随机图像旋转、边界框平移等数据增强扰动来缓解类别不平衡。论文进一步将该方法扩展为两阶段框架并在 AFLW 与 300W 数据集上验证了 Wing Loss 的有效性论文原摘要见算法卡片 wingloss.md此处超越当时 SOTA为论文自身结论。Wing Loss 数学定义与源码实现分段定义与平滑常数Wing Loss 的数学形式如下wing(x) ω·ln(1 |x|/ε) if |x| ω |x| - C otherwise C ω·(1 - ln(1 ω/ε))其中ωomega也被称为宽度width决定对数区间的边界εepsilon也被称为曲率curvature控制对数函数的弯曲程度C保证分段函数在|x| ω处平滑衔接的常数。MMPose 中的 WingLoss 类MMPose 在 mmpose/models/losses/regression_loss.py#L222-L289 中实现了WingLoss并通过MODELS.register_module()注册为可配置的损失模块。其构造函数默认参数为MODELS.register_module() class WingLoss(nn.Module): def __init__(self, omega10.0, epsilon2.0, use_target_weightFalse, loss_weight1.):四个参数的含义与默认值如下参数默认值含义omega10.0分段边界宽度 ωepsilon2.0对数曲率 εuse_target_weightFalse是否使用逐关键点权重不同关键点类型可有不同权重loss_weight1.0该损失在整个 loss 中的权重系数平滑常数在初始化阶段一次性计算见 regression_loss.py#L246-L248# constant that smoothly links the piecewise-defined linear # and nonlinear parts self.C self.omega * (1.0 - math.log(1.0 self.omega / self.epsilon))核心前向计算在criterion方法中regression_loss.py#L250-L266其张量形状约定为[N, K, D]batch_size N、关键点数 K、坐标维度 D2 或 D3即适用于坐标回归型头部def criterion(self, pred, target): delta (target - pred).abs() losses torch.where( delta self.omega, self.omega * torch.log(1.0 delta / self.epsilon), delta - self.C) return torch.mean(torch.sum(losses, dim[1, 2]), dim0)可以看到torch.where正是分段定义的可微实现——delta omega时取对数项放大误差否则取线性项delta - C最终对每个样本的所有关键点坐标求和后取均值。当use_target_weightTrue时forward会先对输出与目标同时乘上target_weight再计算损失regression_loss.py#L282-L289从而支持对遮挡、难易不同的关键点区别对待。坐标归一化的必要性Wing Loss 的边界 ω 与曲率 ε 均以坐标单位像素设定因此在 MMPose 中它与RegressionLabel编解码器配合使用该 codec 会把关键点坐标归一化到[-1, 1]区间配置见 mmpose/codecs/regression_label.py使回归目标与 ω、ε 的量纲匹配避免因输入尺寸不同导致的对数区间失效。Wing Loss 的两个变体SoftWingLoss 与 AdaptiveWingLossMMPose 在 Wing Loss 基础上还实现了两个同族变体便于研究者横向对比与替换。SoftWingLoss坐标回归版SoftWingLoss位于同一文件 regression_loss.py#L292-L359其定义来自 TIP 2021 论文Structure-Coherent Deep Feature Learning for Robust Face Alignmentloss |x| , if |x| ω1 ω2·ln(1 |x|/ε) B , if |x| ω1 B ω1 - ω2·ln(1 ω1/ε)与 Wing Loss 的区别在于小误差区间直接使用 L1|x|对数区间由 ω2、ε 控制衔接常数记为B。默认参数为omega12.0, omega220.0, epsilon0.5regression_loss.py#L310-L315。其实现同样通过torch.where完成分段计算regression_loss.py#L328-L344。AdaptiveWingLoss热图回归版AdaptiveWingLoss位于 mmpose/models/losses/heatmap_loss.py#L282-L371出自 ICCV 2019 论文Adaptive Wing Loss for Robust Face Alignment via Heatmap Regression。它面向热图heatmap回归任务张量形状[N, K, H, W]把 Wing Loss 扩展到逐像素、逐关键点自适应的形式通过指数项(α - target)让损失对预测热图值敏感。默认超参数为alpha2.1, omega14, epsilon1, theta0.5heatmap_loss.py#L295-L301其中 θ 是分段阈值。三类损失在 mmpose/models/losses/init.py#L7-L19 中统一导出并注册均可直接以字符串形式在配置中引用。在 MMPose 中复现 Wing Loss 训练仓库在 configs/face_2d_keypoint/topdown_regression/wflw/ 下提供了基于 WFLW 数据集的完整实验配置其中包括 Wing Loss 与 SoftWing Loss 两个版本td-reg_res50_wingloss_8xb64-210e_wflw-256x256.pytd-reg_res50_softwingloss_8xb64-210e_wflw-256x256.py以 Wing Loss 配置为例模型部分的结构如下codec dict(typeRegressionLabel, input_size(256, 256)) model dict( typeTopdownPoseEstimator, data_preprocessordict( typePoseDataPreprocessor, mean[123.675, 116.28, 103.53], std[58.395, 57.12, 57.375], bgr_to_rgbTrue), backbonedict( typeResNet, depth50, init_cfgdict(typePretrained, checkpointtorchvision://resnet50), ), neckdict(typeGlobalAveragePooling), headdict( typeRegressionHead, in_channels2048, num_joints98, lossdict(typeWingLoss, use_target_weightTrue), decodercodec), train_cfgdict(), test_cfgdict( flip_testTrue, shift_coordsTrue, ))关键点解读codec使用RegressionLabel输入尺寸256×256坐标被归一化后作为回归目标backboneImageNet 预训练的 ResNet-50neckGlobalAveragePooling将特征图压成 2048 维向量headRegressionHead直接回归 98 个关键点的归一化坐标损失配置为WingLoss并开启use_target_weight启用 wflw.py 数据集提供的关键点可见性权重test_cfg开启水平翻转测试融合flip_testTrue与坐标移位shift_coordsTrue。训练配置td-reg_res50_wingloss_8xb64-210e_wflw-256x256.py#L4-L27要点如下配置项取值说明max_epochs210总训练轮数每 10 轮验证一次optimizerAdam, lr5e-4使用 Adam 优化器warm-upLinearLR前 500 itersstart_factor0.001前 500 次迭代线性预热lr scheduleMultiStepLRmilestones[170, 200]gamma0.1第 170/200 轮学习率衰减 10 倍auto_scale_lrbase_batch_size512按实际 batch size 自动缩放学习率batch_size训练 64 / 验证 32数据加载配置checkpointsave_bestNME, ruleless按 NME 指标保存最优权重数据增强与 pose-based data balancing 的落地论文提出的 pose-based data balancing复制少数姿态样本 随机扰动对应到 MMPose 配置中体现为训练流水线里的随机几何增强td-reg_res50_wingloss_8xb64-210e_wflw-256x256.py#L64-L75train_pipeline [ dict(typeLoadImage), dict(typeGetBBoxCenterScale), dict(typeRandomFlip, directionhorizontal), dict( typeRandomBBoxTransform, scale_factor[0.75, 1.25], rotate_factor60), dict(typeTopdownAffine, input_sizecodec[input_size]), dict(typeGenerateTarget, encodercodec), dict(typePackPoseInputs) ]其中RandomBBoxTransform的rotate_factor60±60° 随机旋转与scale_factor[0.75, 1.25]缩放扰动正是对训练样本做旋转、平移类扰动以增强姿态多样性的实现RandomFlip提供水平翻转TopdownAffine将裁剪区域仿射变换到256×256GenerateTarget依据RegressionLabel生成归一化坐标目标。评测配置评测采用 NMENormalized Mean Error归一化平均误差指标归一化方式为keypoint_distance按关键点间距离归一化此处为 WFLW 约定的人眼中心间距并在推理阶段叠加水平翻转融合以降低误差td-reg_res50_wingloss_8xb64-210e_wflw-256x256.py#L114-L121default_hooks dict(checkpointdict(save_bestNME, ruleless)) val_evaluator dict( typeNME, norm_modekeypoint_distance, ) test_evaluator val_evaluator训练与测试命令按 configs 目录的组织方式训练与测试该配置的命令为单卡示例多卡可参考 tools/dist_train.sh 与 tools/dist_test.sh# 训练 python tools/train.py configs/face_2d_keypoint/topdown_regression/wflw/td-reg_res50_wingloss_8xb64-210e_wflw-256x256.py # 测试 python tools/test.py configs/face_2d_keypoint/topdown_regression/wflw/td-reg_res50_wingloss_8xb64-210e_wflw-256x256.py checkpoint路径运行前需按 docs/zh_cn/user_guides/prepare_datasets.md 准备 WFLW 数据集并将其放置在配置中指定的data/wflw/目录下annotation 路径为annotations/face_landmarks_wflw_train.json与annotations/face_landmarks_wflw_test.json。实验结果WFLW 上的评测记录模型卡片 resnet_wingloss_wflw.md 记录了该配置在 WFLW 测试集上的评测结果模型在 WFLW 训练集上训练输入尺寸 256×256ResNet-50 Wing Loss 取得的 NME 为4.67该数值来源于仓库模型卡片记录的实验日志具体权重与日志下载地址见该模型卡片。在 resnet_softwingloss_wflw.md 中可找到 SoftWing Loss 的对应评测记录两套配置除head.loss一行外完全一致方便直接对比两种损失函数的精度差异。测试验证与扩展阅读仓库的单元测试对 Wing 家族损失的正确性做了数值验证在 tests/test_models/test_losses/test_heatmap_losses.py#L11-L37 中TestAdaptiveWingLoss构造了零值/常值预测与标签校验了AdaptiveWingLoss在有无target_weight两种模式下的输出数值例如全 1 预测对全 0 标签在默认参数下应输出约 8.4959可作为复现数值实现的参考锚点坐标回归侧的WingLoss/SoftWingLoss均注册在 mmpose/models/losses/init.py 中可直接 import 后单测验证。如需进一步了解相关变体与应用场景可继续阅读仓库内以下内容热图回归版的 Adaptive Wing Loss 配置td-hm_hrnetv2-w18_awing-8xb64-60e_wflw-256x256.py对应算法卡片 awingloss.md人脸关键点回归基准总览configs/face_2d_keypoint/topdown_regression/README.md回归编解码器原理mmpose/codecs/regression_label.py 与 docs/en/advanced_guides/codecs.md。小结Wing Loss 通过在(-w, w)区间内以修正对数函数放大小、中误差的梯度贡献缓解了 L2/L1 类损失在小误差区梯度平缓、收敛不精细的问题是坐标回归式人脸关键点定位的重要损失函数之一。在 MMPose 中它通过 WingLoss、SoftWingLoss坐标回归与 AdaptiveWingLoss热图回归三个注册模块被原生支持配合RegressionLabelcodec、RandomBBoxTransform姿态增强与 NME 评测体系可在 WFLW 等基准上开箱复现。论文中的 pose-based data balancing 思想也通过旋转、缩放、平移等随机几何增强在训练流水线中得到落地。【免费下载链接】mmposeOpenMMLab Pose Estimation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmpose创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网