自监督学习如何破解AU检测标注困局:视频预训练与微调实战

发布时间:2026/10/14 1:28:54
自监督学习如何破解AU检测标注困局:视频预训练与微调实战 做面部行为分析的人应该都绕不开动作单元Action UnitAU这套体系。之前我在一个真实项目里做AU检测最头疼的不是模型结构选哪个而是标注成本实在太高。AU不是像开心、难过那种整体表情它要标记的是眉毛上提几毫米、嘴角向斜上方拉扯多少甚至需要受过FACS编码训练的专业人员逐帧打标。项目做到一半我发现团队每天能产出的有效标注帧非常有限模型表现始终上不去。后来我仔细研究了一篇思路很有代表性的工作CVPR 2019的《Self-supervised Representation Learning from Videos for Facial Action Unit Detection》。这篇论文的核心想法很直接如果监督数据这么贵那我能不能让模型先在海量无标注视频上自己学一遍面部动态特征再用少量标注数据做微调实际跟做下来我觉得这个方向比单纯堆监督数据要靠谱得多。这篇文章我就从论文思路、预训练任务设计、微调适配以及我自己踩过的坑这几个角度完整拆一遍。1. AU检测的真实瓶颈为什么常规监督学习在这里吃力不讨好1.1 动作单元与表情识别的根本区别新手容易把AU检测和表情识别当成一回事实际上两者的难度完全不在一个量级。表情识别面对的通常是整体情绪状态比如惊讶往往伴随眉毛上扬、眼睛睁大、嘴巴张开这种模式非常显著CNN提取的全局外观特征就能区分得很不错。而AU检测要面对的是局部、微小、持续时间可能很短暂的面部肌肉变化比如AU6 cheek raiser 单独出现的时候可能只是脸颊肌肉轻微收缩人眼都不太容易察觉。正是这种细粒度特性决定了AU检测对特征的定位能力要求非常高。全局池化后的特征向量很容易把某个区域的细节平均掉导致模型只能记得大概哪里在动却说不清具体某个局部是否达到动作强度阈值。这也是为什么很多从业者在一开始套用表情识别模型做AU时效果都很差。1.2 标签成本、类别不平衡与个体差异AU检测的标注成本有多高这里说个实际经历。我们当时找标注人员做AU标注光培训就花了两周期间要让他们熟练记忆每个AU编号对应的肌肉动作和强度等级。正式标注时单人单张图的耗时大概在10秒到30秒之间而且必须参照视频上下文判断因为很多AU的标签在单帧里是有歧义的。更麻烦的是类别不均衡。面部AU一共可以分成几十种但实际数据集里高频出现的往往只有那十几种左右比如AU1、AU2、AU4、AU6、AU12、AU25等等而像AU15嘴角下压、AU17下巴上提这类出现频率要低得多。如果直接二分类训练少数类AU几乎等于被模型忽略。个体差异也在叠加难度同样是AU12嘴角拉伸不同人的幅度和形态差异极大模型很容易把人脸ID当作AU标签的相关特征导致跨人泛化能力变差。1.3 从视频里白嫖监督信号的动机既然人工标注这么贵那么能不能找到一个不用人工标签、但依然能教会模型面部动态的监督来源视频天然就是这样的金矿。一张静态图只包含空间信息但一段视频里包含了时间顺序、运动趋势、相位关系这些额外信息。比如一个人从平静到微笑视频里记录了肌肉的变化过程如果倒过来播放模型看到的运动方向和正向播放是不同的。这些时间属性不需要任何人工标注是视频数据自带的。用这些自带的属性构造任务让模型通过完成任务来学习特征这就是自监督表示学习的核心思路。我当时看到这篇论文时最认可的一点就是它把眼光放在视频上而不是单帧图像上这对AU检测来说非常关键。因为AU本身就是动作单元离开了时间变化过程单从静态外观学到的特征天然是残缺的。2. 自监督表示学习的核心逻辑视频里天然存在的时间标签2.1 自监督学习的通用思路构造伪任务自监督学习的基本套路可以概括成一句话扔掉人工标签构造一个模型必须理解数据本身才能完成的伪任务。模型为了完成伪任务被迫学会提取有用的语义特征这些特征后来可以迁移到真正关心的下游任务上。常见的伪任务包括预测图像的旋转角度、给图像块做拼图、判断两帧的时间顺序、从损坏的帧重建完整帧等等。伪任务设计得好不好决定了中间特征是否真的有用。好的伪任务会让模型不得不去理解对象结构、运动规律和上下文关系而不是去记一些捷径。以视频为例最经典的伪任务之一就是时间顺序判断给定一个片段判断它是正向播放还是反向播放。模型要完成这个任务不能只看静止的纹理它必须理解眉毛从高到低和眉毛从低到高的区别必须感知动作的方向和先后顺序。这种感知恰好是AU检测需要的能力。2.2 为什么视频比静态图像更适合AU特征学习很多人会问直接用ImageNet预训练的模型来做AU检测不行吗行但效果天花板很低。ImageNet上的预训练教会了模型识别物体类别它确实能提取很好的通用纹理特征但对运动幅度随时间变化这类动态信息几乎没有建模能力。实验里很容易看到这个差距把同一张人脸做很小的平移、旋转或缩放ImageNet预训练模型的特征变化可能不大但把眉毛从平静状态到抬升状态的5帧图像给模型看它的特征表示往往区分度不够。换句话说静态预训练的特征是外观敏感的而AU检测需要的是运动敏感的特征。视频自监督恰好补上了这一点。模型在预训练阶段反复观察成千上万段面部视频学会了把帧与帧之间的差异编码进特征里。等到了下游AU检测任务时这些特征天然就带有动态变化的敏感性微调需要的数据量和轮次都会显著下降。2.3 整体框架预训练编码器与下游检测头从工程结构上看这篇论文的做法很清晰一个可复用的视觉编码器加一个预训练期间使用的自监督头再加一个下游任务微调时替换的检测头。编码器通常是标准的CNN结构比如常见的ResNet系列自监督头负责把编码器输出的特征转换成伪任务需要的输出比如时序顺序的分类结果或者局部区域的重建结果。预训练完毕之后自监督头被丢弃编码器的权重被保留下来作为初始化。下游AU检测任务中在编码器后面接一个多标签分类头每个AU一个输出节点用BCE损失微调。整个流程和常规的迁移学习非常相似区别只在预训练阶段的标签来源。这个框架在工程上很好落地因为它没有引入复杂的模型结构需求只要你有一个能在视频上跑得动的CNN就能把预训练任务接上去。我后来复现时发现只要数据组织方式正确训练流程整体非常顺滑。3. 预训练任务的设计细节局部区域与全局时序协同3.1 局部动作建模细粒度AU需要的空间精度AU检测的难点之一是局部独立性。同样是嘴巴区域AU12是嘴角向斜上方拉伸AU15是嘴角向下压AU17是下巴向上顶这些动作发生在几乎同一个部位但方向和语义截然不同。如果模型只学到嘴巴区域在动那显然不够它必须学到嘴巴区域的哪个子部位朝哪个方向产生了多大位移。这篇论文里很重要的一条线就是把面部特征图划分成多个局部区域分别建模。具体操作上编码器输出的feature map会按空间位置被切成小块每一块对应面部的某个局部区域。预训练时模型要分别预测每个局部区域在当前帧和相邻帧之间的关系相当于逼着模型的每一块特征都学会跟踪自己负责的那块面部肌肉。这里有个很值得借鉴的设计思路不是把所有区域的特征拼在一起做整体预测而是让每个区域独立地参与预测。这样做的好处是模型不会因为某个区域动作显著就忽略其他区域的动作有效缓解了局部AU被全局特征淹没的问题。我在复现时严格保留了这种区域独立的策略效果确实比全局特征直接做预测要好。3.2 全局时序一致性从帧间顺序中学习动作方向局部建模解决的是哪里在动的问题但AU检测还需要回答怎么动的问题。这里论文用的是全局时序一致性约束。具体来说预训练任务会构建一个时间判别任务给模型输入一段长度为T的连续帧序列随机决定把序列按正向还是反向排列然后让模型判断当前输入的是正向序列还是反向序列。因为正向和反向序列在单帧外观上可能几乎一致模型必须捕捉相邻帧间的时序依赖才能正确判断运动方向。这个任务看起来简单但要做到高准确率并不容易。模型必须理解面部动作的正常时间顺序比如从平静到微笑是AU12的强度逐渐上升反过来则是下降。这种对动作轨迹的建模我后来发现对下游AU强度预测特别有帮助尤其是在标注数据只有存在性标签、没有细粒度强度标签的情况下。3.3 损失函数组合与训练策略预训练的总损失通常是局部建模损失和全局时序损失的加权和。这里有一个在实际操作中很重要的点两个损失的尺度可能差异很大直接相加会导致数值大的一方主导训练。我的处理方式是在损失上加可学习的损失权重或者通过实验观察损失尺度来手工配平。一个相对稳定的起点是让全局时序损失的权重略大于局部损失因为时序任务作为整体目标信号更稳定局部损失则用来微调特征的空间敏感度。两个损失共同训练时需要特别注意学习率不宜过大否则区域级特征很容易出现过拟合到训练集运动模式的问题。另外序列长度和采样帧间隔也是两个关键超参。序列太短时序信息不足序列太长模型会承担过高的内存开销。帧间隔太小相邻帧变化微乎其微帧间隔太大动作过程可能被跳过。我试验下来帧间隔在2到4帧之间序列长度在7到9帧左右是一个兼顾信息量和开销的甜点区间。3.4 可复现的预训练流程伪代码下面这个伪代码不是我凭空写的是我在复现和改编这篇论文思路时实际使用过的一个简化流程可以当作一个起点参考。# 伪代码视频自监督预训练流程 import torch import torch.nn as nn class PoseEncoder(nn.Module): def __init__(self, backbone): super().__init__() self.backbone backbone self.global_head nn.Sequential( nn.AdaptiveAvgPool2d((1, 1)), nn.Flatten(), nn.Linear(512, 256), nn.ReLU(), nn.Linear(256, 2) # 正向/反向二分类 ) self.regional_head nn.Sequential( nn.Conv2d(512, 256, 1), nn.ReLU() ) def forward(self, x): feat self.backbone(x) # [B, C, H, W] return feat def regional_consistency_loss(feat, grid_size4): # feat: [B, T, C, H, W] 已按时间展开 # 切成 grid_size x grid_size 的区域分别对比相邻帧特征 loss 0.0 patches [] B, T, C, H, W feat.shape ph, pw H // grid_size, W // grid_size for i in range(grid_size): for j in range(grid_size): region feat[:, :, i*ph:(i1)*ph, j*pw:(j1)*pw] region region.mean(dim(3, 4)) # [B, T, C] patches.append(region) for p in patches: diff p[:, 1:] - p[:, :-1] loss loss diff.pow(2).mean() return loss / (grid_size * grid_size) def train_step(model, frames, labels): # frames: [B, T, C, H, W] B, T, C, H, W frames.shape frames_flat frames.view(B * T, C, H, W) feats model.backbone(frames_flat) # [B*T, C, H, W] feats feats.view(B, T, feats.size(1), feats.size(2), feats.size(3)) # 全局时序头所有时间帧聚合后判断顺序 seq_feat feats.mean(dim1) # [B, C, H, W] pred_order model.global_head(seq_feat) loss_order nn.CrossEntropyLoss()(pred_order, labels) # 局部区域一致性 loss_region regional_consistency_loss(feats, grid_size4) loss 0.6 * loss_order 0.4 * loss_region return loss这个流程里我会在每次迭代时随机打乱时间顺序生成标签同时保持镜头内容不变。实际跑下来我建议先在小规模视频子集上验证损失能否正常下降再放全量数据训练能省下很多排查时间。4. 从预训练到动作单元检测微调策略与工程细节4.1 下游任务头的替换与初始化预训练完成后自监督头基本就没有利用价值了可以整体丢弃。需要替换的是检测头这部分要重新随机初始化不能直接沿用预训练头的参数。为什么不能沿用因为预训练头学到的输出空间是时间顺序之类的伪标签空间和AU存在的语义空间完全不同直接沿用反而会让分类器一开始处于混乱状态。反过来编码器部分必须继承预训练权重这是整个自监督流程的价值所在。如果编码器也用随机初始化那自监督预训练就白做了。微调时的网络结构很简单编码器提取最后一层特征图经过全局平均池化接一个多标签分类头。分类头的输出节点数和目标AU类别数一致每个节点对应一个AU是否存在。考虑到AU之间的相关性比较强比如AU1和AU2经常同时出现最后一层线性分类器不需要刻意建模相关性BCE损失会自动让特征适配这种共现模式。4.2 数据对齐与增强微调阶段的第一步不是调参做AU检测微调时我踩过最大的坑是输入图像的对齐。AU标签是相对于标准人脸姿态定义的也就是说模型最好在一张正面化的人脸上做判断。如果直接把原始视频帧丢进网络头部姿态一变同一个AU显示出的外观形态完全不同模型很容易把姿态当作AU特征来学泛化能力会急剧下降。所以微调前的数据预处理至少要包含人脸检测、关键点定位和人脸对齐三个步骤。较通用的做法是检测五个关键点双眼中心、鼻尖、嘴角两端然后做仿射变换把人脸转换为统一的姿态和尺度。这一步看着不起眼但对最终精度的影响比我调任何损失函数都明显。对齐之后的归一化也很重要。不同人脸肤色、光照差异很大我会对图像做逐通道均值方差归一化同时在训练时适度加入亮度扰动、轻微旋转和水平翻转。水平翻转需要注意AU是有左右属性的翻转后会互换左右AU标签所以翻转必须同步翻转标签否则模型会学到错误的左右映射关系。4.3 类别不平衡的处理加权BCE与阈值调整AU检测是个标准的多标签分类问题每个AU的阳性样本比例差异很大。常用来处理不平衡的加权BCE这里的权重设置必须结合数据集本身的样本分布来算不能直接照搬论文里的值。权重计算方式我是这样做的统计每个AU在训练集中的阳性占比p权重设为负样本数量除以正样本数量再做一个截断限制防止权重过大导致训练不稳定。实际操作时我会额外引入一个难例挖掘机制对误分类样本加大损失权重。这个技巧在小样本AU上尤其有效能让模型把注意力放在那些看起来很少有、但确实存在的AU上。另外还有一个工程细节分类阈值。很多模型输出的AU概率分布并不是天然偏置在0.5左右尤其是正样本占比很低的AU模型输出往往整体压低。所以我不会生硬地用0.5作为判定阈值而是在验证集上逐类搜索最优阈值。虽然操作上多一步但对最终F1分数的提升非常明显。4.4 消融实验视角哪些模块真正有用我在复现过程中把预训练模块做了几组消融得到的结论和论文给出的整体方向一致同时使用局部区域建模和全局时序建模效果优于只使用任何一种而使用静态图像预训练或者直接用ImageNet初始化最终AU检测的F1分数都会低一个档次。更让我印象深刻的是把区域网格数量从1提升到4、再到8精度的提升在4格到8格之间开始变缓。这说明局部特征确实有用但也不是切得越细越好切得太细会让每个区域包含的上下文太少反而丢失了区域之间的相关性。实际操作时我会根据输入分辨率来定网格如果输入是112x112左右4到6格是性价比最高的区间如果分辨率更大可以适当增加网格数。5. 我踩过的坑与落地心得5.1 预训练数据不能只贪多质量要过三关理论上自监督学习吃的数据越多越好但实际工程里低质量视频反而会拖累预训练效果。我第一版预训练数据集收了几万段人像视频没有做太多筛选训练出来的模型在下游微调时表现一般还不如用更小但更干净的子集。我给预训练数据做了三道过滤第一剔除没有人脸或者人脸占比过小的帧第二剔除严重模糊、遮挡、过曝的帧第三保留视频帧连续性丢弃那些画面跳动剧烈、剪辑切换频繁的片段。这里的逻辑是自监督模型学的本质是连续动态变化如果视频片段本身是跳变的模型学到的时间动态就是错乱的特征质量自然受影响。5.2 时间顺序任务的捷径问题在做时序判断这个伪任务时有一个让我印象深刻的陷阱模型会在跳到画面局部像素统计差异这类低级线索上而不是真正理解动作顺序。具体来说如果视频片段里包含明显的镜头切换、亮度闪烁、或者比较大的头部整体运动模型只需要判断前半段和后半段平均像素是否类似就能猜对顺序根本不需要区分AU动作方向。结果是预训练损失降得很快但提取出来的特征对AU检测没有任何增益。我的解决办法是预训练输入尽量使用静态背景下的人脸近景视频并且在每个训练序列里避开镜头切换此外还可以把帧间亮度差异做归一化减小非肌肉运动带来的干扰。后来我甚至尝试过给输入施加轻微的随机遮挡强迫模型不能依赖单一区域的像素统计来做顺序判断效果也不错。5.3 与对比学习结合的现实选择现在再回头看这篇CVPR 2019的工作可能有人会觉得它的自监督任务设计比对比学习简单没有用到InfoNCE那套复杂的正负样本机制。但我在实际组合使用时发现简单的时序判别任务反而可以当作对比学习的一个补充两者并不冲突。对比学习擅长学语义不变性比如同一张人脸在不同光照、不同姿态下特征保持一致而这种视频时序任务擅长学动态变化敏感性可以捕捉AU这种短期肌肉位移。我在一个真实项目里把两者结合先用对比学习做基础表示训练再用视频时间顺序任务做第二轮精修最后微调AU检测头。最终结果比单独用任何一种都好这算是我从这篇论文里得到的最有价值的一个扩展思路。5.4 落地时的算力与工程考量最后说句实在话视频自监督预训练对算力是有要求的尤其是长视频序列显存占用会成倍上涨。如果条件有限不一定要完整复现整篇论文的预训练流程完全可以下载公开的人脸视频特征预训练权重来做初始化再用自己的少量标注数据微调。这样做的精度虽然比完整效果略低但胜在速度快、门槛低特别适合中小团队。如果决定自己预训练我建议从短序列、低分辨率开始先把整个流程跑通确认损失收敛正常再逐步加大序列长度和分辨率。上来就开大分辨率长序列很容易在细节参数上浪费大量调试时间。我个人在实战里的体会是AU检测这类任务决胜点往往不在模型结构有多新奇而在你给模型提供了什么样的学习任务。视频自监督的意义是让模型在没有人工标注的前提下提前掌握了面部动态的时间和空间规律。后续哪怕只有几千张带标注的面部图像也足够微调出一个能在真实场景落地的AU检测模型。如果你的项目正好卡在标注成本高、AU精度低这个阶段不妨沿着这条思路试试先用视频把编码器喂饱再带着少量标注做精准适配路径会比想象中更顺畅。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询