第一次接触微表情识别是因为一个很具体的问题普通表情识别已经在公开数据集上做到非常高的准确率了为什么还要单独研究一个“微表情”我当时以为无非是把检测阈值调得更灵敏、把特征算得更细一点本质上还是同一件事。直到认真读完一篇微表情识别的综述才意识到这两个方向从数据采集、任务定义到评测方式几乎没有一环是重叠的。这篇笔记就是我在读综述过程中整理出来的框架主要围绕微表情识别到底在做什么、数据集是怎么来的、方法如何演进、检测和识别为什么要分开看以及复现实验时容易踩的评估这些环节。如果你准备入门微表情识别或者只是好奇它为什么不像普通表情识别那样“大力出奇迹”这篇笔记应该能让你少翻不少文献。我会尽量不预设你已经具备很强的视觉基础把综述里那些容易被一句话带过、但对建立整体认知很关键的地方都展开讲。1. 微表情识别到底在识别什么任务定义和容易混淆的概念1.1 微表情不是“弱化版的表情识别”综述里对微表情的标准描述一般会落在三个特征上持续时间短、运动幅度小、只发生在局部区域。心理学上通常把微表情的持续时间定义在0.04秒到0.2秒左右也有说法是不到瞬间就结束。这个时长有多夸张呢普通表情通常能持续0.5秒甚至好几秒你可以在对话中明确观察到对方的嘴角上扬或眉毛紧锁。而微表情是一闪而过的局部动作比如嘴角只微微抽动一下就恢复或者眉毛中间肌肉极短促地收缩动作幅度小到容易被认为是面部抽搐或光线抖动。正因为如此微表情识别从来不是“把表情识别模型的灵敏度调高一点”就能解决的问题。普通表情帧与帧之间的状态差异明显特征表达相对稳定微表情则需要在很短的时间和很小的空间范围内捕捉到精细的运动模式这对数据采集设备、标注粒度和算法都能处理细节信息的能力都有完全不同的要求。1.2 检测与识别是两个不同层级的任务我在读综述时最容易混淆的一个点就是“检测”和“识别”。很多入门文章把两个词混着用但综述里从头到尾都在强调它们是完全分开的任务。微表情检测spotting/temporal localization解决的是“微表情在视频里哪个时间段出现了”。它本质上是时序事件定位非常像一个警报系统在几十秒甚至几分钟的视频里绝大部分时间都是无表情或普通表情只有极少数片段发生了微表情。你要做的就是把这段区间找出来。微表情识别recognition解决的是“给定一段已经确定的微表情片段它表达的是什么情绪类别”。它更像分类问题输入已经知道是微表情的视频片段输出是高兴、惊讶、厌恶、压抑、紧张等类别。综述里的常见做法是先讲检测再讲识别不是因为它们只是顺序关系而是因为它们的难度来源完全不同。检测难在“正负样本极度不均衡”识别难在“类别之间差异太小”。实际落地时两个任务要串联起来但学术研究和实验设计上必须分开建模和评估。这是我读完综述后印象最深的一点。1.3 为什么微表情识别长期没有爆发式进展普通表情识别能依赖大规模数据集微表情识别则长期受制于几个结构性困难。第一是数据规模极小。目前最常用的自发微表情数据集样本量也就一两百个片段这和普通表情数据集动辄几万几十万张图片完全不在一个量级。深度学习是数据饥渴型的喂不饱模型性能自然上不去。第二是标注成本高。微表情需要标注的不是“这张图是什么表情”而是要标出动作发生的起始帧、峰值帧、结束帧还要标注动作单元和情绪类别。这些标注需要受过训练的心理学专业人员参与而且不同标注者之间的一致性很难保证。对同一段视频可能有人觉得是厌恶有人觉得是困惑这会直接限制监督学习的上限。第三是类间差异小。微表情的几个类别在纹理和运动模式上高度相似比如“压抑的愤怒”和“紧张”在局部肌肉运动上可能就是毫米级别的差异。对人眼来说都很困难对计算机来说自然更不轻松。理解了这三点再看后面的数据集和方法设计很多决策逻辑就顺理成章了。2. 第一个拦路虎是数据主流数据集与刺激范式的门道2.1 常见数据集与它们的关键差异微表情识别绕不开数据。综述里反复出现的就是几个名字SMIC、CASME、CASME II、SAMM。我整理了一个简表方便对照看数据集被试人数约微表情片段数约帧率主要特点SMIC16164100 fps最早被广泛使用的自发微表情数据集之一CASME35200左右低于200 fps情绪类别以抑制情绪为主与日常生活接近CASME II26247200 fps分辨率高标注精细后来绝大多数论文都在它上面测试SAMM32159200 fps被试多元化标注动作单元较细不要小看帧率这个参数。普通视频30 fps每两帧之间的间隔约33毫秒而微表情可能只有0.2秒也就是六帧左右如果动作更短甚至只有两三帧。在30 fps下微表情很容易被完全吞掉。而200 fps下0.2秒的微表情能记录到40帧左右算法才有机会捕捉到完整的运动过程。这也是为什么CASME II和SAMM成为主流基准数据集的硬件原因——它们的高帧率决定了能捕捉到足够多的时序细节。2.2 微表情数据是怎么“诱发”出来的读综述时我最好奇的部分是这些微表情片段到底怎么采集的。普通表情数据集里让被试对着摄像头做表情就行但自发性微表情的最大特征是“被试自己都不知道自己暴露了情绪”这就必须通过特定的实验范式去诱发。主流做法有两种。一种是高唤醒视频刺激给被试播放能引发强烈情绪的影片片段同时要求他们尽量保持面无表情。人在刻意压抑真实情绪时面部会出现短暂的微表情泄漏。另一种是访谈/欺骗范式设计一个需要被试说谎或者掩盖真实反应的任务利用心理学上的认知负荷诱导微表情。这两种范式都强调“自发性”而不是“扮演”。扮演出来的微表情往往肌肉配合得更完整、持续时间更长和真实情境下的微表情分布不一样。这一点直接影响了模型的泛化能力在扮演数据上训练出来的系统拿到真实场景里通常表现会下降得很明显。2.3 标注为什么这么贵且难微表情数据集的标注比普通表情复杂得多。标注人员需要逐帧观看200 fps的视频帧确认微表情从哪一帧开始出现、哪一帧肌肉运动达到峰值、哪一帧结束并记录对应的面部动作单元。动作单元是基于面部动作编码系统定义的比如“内眉上扬”对应AU1“嘴角上扬”对应AU12。一个30秒的片段逐帧标下来可能要花一两个小时而且多人标注后还要做一致性检验。这也是我在读综述时产生的一个具体体会微表情识别的问题瓶颈可能很长一段时间内都不只是模型结构而是高质量标注数据的生产能力。深度学习再强没有可靠的标签也是无米下锅。3. 方法是怎么从“特征工程”一步步走到“端到端”的3.1 手工特征时代从时空纹理到光流统计综述里对早期方法的梳理主线是从时空特征到运动特征的演变。早期研究者把微表情当作一个三维时空体来处理x和y是空间坐标t是时间轴。最经典的特征是LBP-TOP它在三个正交平面上分别提取局部二值模式再把三个方向的直方图拼起来描述时空纹理。另一条线是光流特征。微表情虽然幅度小但本质上是一种局部运动而光流法天生就是用来估计像素运动的于是很自然地成了微表情识别的重要工具。常见做法是在微表情片段内先计算光流场再用方向直方图的方式聚合光流信息得到紧凑的特征描述。这种特征强调“运动方向”而不是“静态纹理”对微弱运动更敏感。拿到特征之后早期分类器以SVM和极限学习机为主。现在回头看在CASME II这类小数据集上手工特征配合SVM的表现并没有被早期深度学习方法碾压多少在某些协议下甚至互有胜负。这不是说手工特征更强而是说明在数据规模极小的情况下精心设计的特征确实能弥补模型容量的不足。3.2 深度学习时代从“空间编码时序建模”到“时空一体”综述的后面部分集中在深度学习方法。最直观的思路是把视频当作图片序列对每一帧先做空间编码再用循环神经网络建模时序也就是CNNLSTM的组合。这种思路容易理解但在微表情场景下有一个明显问题微表情的判别信息集中在细微运动里如果单帧空间编码丢失了运动幅度信息后面用LSTM也救不回来。第二种思路是直接用3D-CNN。把连续帧堆叠成三维输入卷积核在空间和时间两个维度同时滑动理论上能够同时捕捉空间外观和时序运动。不过3D卷积参数量大在小数据集上很容易过拟合所以后来的工作要么从预训练权重初始化要么在光流序列上做3D卷积用光流把“微弱运动”这个信息显式地提供给网络。第三种思路是注意力机制和Transformer。空间注意力可以提示网络该看脸部的哪一块时序注意力可以告诉网络该在哪几帧集中注意力。对微表情来说这个方向天然合理不是每一帧都贡献相同的信息峰值帧附近的运动信息最丰富注意力机制正好学这种权重分配。3.3 光流在深度学习方法里的地位依然重要读综述时我注意到一个反复出现的细节即便在端到端深度学习时代光流依然没被抛弃。有些方法把光流作为网络输入有些方法把光流作为多任务学习的辅助监督信号还有一些跨数据集的迁移工作就是靠光流图而不是原始RGB图做适配因为光流图剥离了一部分人种、肤色、光照的差异更接近“纯粹的运动模式”。这一点对我启发很大。微表情识别的难点不是“看清脸”而是“看清脸上的变化”。RGB帧里的眼睛鼻子眉毛是静态外观模型很容易依赖这些信息去猜情绪反而忽略了真正的运动线索。光流相当于告诉模型别看它长什么样看它在动什么。在当前数据规模下这个归纳偏置比模型单纯堆容量更管用。4. 检测与识别是两件事任务拆解和评测设计4.1 微表情检测在长视频里找到转瞬即逝的信号微表情检测之所以难首先是数据极不均衡。一段对话视频里可能只有几帧是微表情剩下都是普通面部活动或静止状态。检测模型如果犯懒把所有片段都判定为“非微表情”准确率可能已经很高但实际没有任何用处。所以检测工作不能只看整体准确率通常要看在特定时间窗口内的定位精确率和召回率以及F1分数。另一个难点是“微表情”和“普通表情”之间存在过渡区。人类面部动作本身是连续变化的一个正常的微笑可能包含和微表情非常相似的运动单元只是持续更长、幅度更大。检测算法需要学习的是“这个短暂的隆起是不是真正的情绪泄漏”这对时序上下文的要求很高只看局部几帧很难判断。综述里介绍的检测方法大体可以分成两类。一类是滑动窗口加分类器对窗口内片段判“有/无微表情”简单但计算量大、窗口长度选择敏感。另一类是把检测当作时序分割任务在整段视频上学习逐帧概率再用后处理合并相邻帧输出区间。后者的思路更接近现在的主流但对帧级标签的要求更高。4.2 微表情识别给定片段判断情绪类别识别任务相对单纯输入是已经裁好的微表情片段输出是情绪类别。这里同样有一个协议细节识别时到底该不该包含微表情出现前后的中性帧。有人习惯只截取从起始帧到结束帧的区间也有人截取前后各几帧中性帧作为上下文。两种方式会显著影响结果因为中性帧提供了“动作是从什么状态开始变化”的参考坐标。综述里会反复提醒读者比较不同方法时必须确认协议一致不然数字对不上是常态。4.3 两个任务串联的工程链条实际系统里检测和识别是串联的摄像头或视频流输入先由检测模块定位微表情片段再把片段送入识别模块分类。这两个模块的错误会相互放大——检测漏掉一个片段识别再好也无济于事检测把普通表情误判成微表情识别模块就会在无意义的数据上瞎猜。这个工程链条也解释了为什么微表情识别实际落地比论文里难论文里往往假设测试数据已经标注好了微表情区间识别模块只需要做分类而现实场景中检测本身就已经是巨大的挑战。读完综述我印象最深的结论之一就是“识别性能重要检测性能同样重要甚至更重要。”5. 复现综述实验时我踩过的评估坑5.1 身份泄漏看起来漂亮的结果很可能无效微表情数据集样本少稍不注意就会引入身份泄漏。最简单也是最常见的错误是随机把片段划分到训练集和测试集。如果同一个被试的多个片段既出现在训练集又出现在测试集模型实际上是在识别“这个人”而不是“这种微表情”。由于微表情和个人面部特征强相关这个泄漏会让性能虚高不少。正确做法是按被试划分。常见协议是留一被试出测试法Leave-One-Subject-OutLOSO也就是每次拿一个被试的所有片段做测试用其余被试的片段训练最后把所有被试的结果汇总。这样测试时模型面对的是完全没见过的人评估结果才更接近真实泛化能力。复现论文时我给自己定的规矩是先看代码或者论文里怎么写划分的如果发现随意随机切分结果再好看也要打问号。5.2 准确率会骗人UAR和UF1才是靠谱的指标微表情识别类别极不平衡有些类别在数据集中只有十几个样本准确率很容易被多数类主导。假设一个数据集里有40%的“平静”样本模型把一切都预测成“平静”整体准确率可能也有40%看起来不是完全没用但实际对少数类一窍不通。综述里通常更看重两个指标未加权平均召回率UAR和未加权平均F1分数UF1。UAR是每个类别的召回率先取平均再对各类做平均这样每个类别的权重一样不会因为某个类样本多就主导结果。UF1则是每个类别的F1取平均同时兼顾精确率和召回率。复现实验后不能只盯着整体准确率还要输出按类别的混淆矩阵看看少数类到底是不是被牺牲了。5.3 小数据集上的“多次运行标准差”一定要写微表情数据集小随机初始化参数和训练数据划分会对结果造成明显波动。我复现时发现同一个模型在相同协议下多跑几次准确率可能差出5个百分点以上。如果论文只给一次运行的结果这个数字很可能是最好的一次甚至是运气最好的一次。更稳妥的做法是每种实验配置重复5到10次报告平均数和标准差。标准差大说明模型不稳定也说明结论不宜过度解读。这一点在读综述时不明显真正动手复现才体会得到。还有一个小细节微表情数据集的样本量小到做大型预训练不现实但很多方法会使用在普通表情或ImageNet上预训练的网络。这时候要检查预训练数据是否包含测试集中的身份或相似尺度的面部图像。如果预训练数据集和测试数据集存在重叠指标就会虚高这种泄漏比划分泄漏更隐蔽。6. 读完综述后的延伸思考应用方向与值得继续挖的选题6.1 微表情识别的现实应用为什么大家执着于它微表情识别的价值很直接因为它难以伪装所以特别适合那些“对方有动机隐藏真实情绪”的场景。比如心理咨询中求访者嘴上说“我没事”但医生可以从微表情里捕捉到更多信息再比如安防和审讯场景微表情可以作为测谎的辅助信号在人机交互里机器如果能感知用户压抑的不满就能在服务变成投诉之前做出调整。这些场景听起来很强但综述里也花了篇幅讨论一个现实问题实验室条件到真实场景的鸿沟。实验室数据是被试坐在固定光源下对着摄像头背景干净、头部基本固定真实场景有头部姿态变化、遮挡、光照不均还有很多复杂的自然交互。模型在数据集上表现再好也不能直接等同于实际效果。这也是我读综述后对“落地”保持审慎态度的原因——方向是对的但中间还隔着大量工程问题。6.2 小数据困境下的几个可行方向综述读到最后我最感兴趣的是如何破解“数据太少”的问题。一个方向是自监督预训练在无标注的普通人脸视频上让模型学会“面部运动变化”的通用表征再在微表情小数据集上微调。这个思路在图像领域已经比较成熟应用到微表情上的核心是设计合适的时间维度预训练任务而不是简单套用图像自监督。另一个方向是跨数据集迁移。不同数据集的被试、采集设备、诱发范式都不一样直接用A数据集训练的模型在B数据集上测试往往掉点明显。如果把多个数据集放到一起训练同时做风格归一化或者特征对齐模型见过的数据分布更丰富泛化性会更好。综述里这部分还提到利用光流图而不是原始RGB图做跨数据集迁移效果通常更稳定。第三个方向是和心理学的动作单元标注做结合。动作单元本身就是跨数据集的通用标签如果先让模型学会预测动作单元再基于动作单元组合判断情绪类别就相当于把“表情分类”这个玄学问题拆成了“哪些肌肉动了”这个相对客观的中间任务。这一点我认为很适合对微表情识别感兴趣的入门者作为研究切入点。6.3 如果要从零复现一篇微表情论文我会怎么做我自己的建议是先不要一上来就跑深度学习大模型。第一步先把数据处理流程跑通把某个数据集的原始视频解帧成图片序列提取每一帧的面部区域计算光流图确保数据增广和样本划分是可复现的。第二步用LBP-TOP加SVM搭一个简单基线运行一次LOSO交叉验证记录UAR和UF1。第三步再去复现一篇深度学习方法重点关注它的输入形态、划分协议和预处理方案。这样一步步下来中间任何一步出了问题你都能定位到是数据处理的问题还是模型的问题而不是最后拿着一个莫名其妙的错误数字无从下手。我自己在复现过程中最常踩的坑是帧率不一致有的数据采集设备是100fps有的是200fps如果不把时间轴换算清楚起步帧、峰值帧和结束帧的对齐就会出错输入给模型的片段长度也会对不上。另一个坑是面部对齐的标准不同的面部关键点检测工具输出的人脸裁剪尺寸和位置不一样导致同样的模型在不同的预处理管线下结果差异巨大。所以复现任何微表情识别论文第一件事就是确认它的预处理细节那些在论文附录里不起眼的描述往往才是决定成败的地方。最后再分享一点个人体会。微表情识别是一个很容易让人产生“我马上就能读心”的错觉的领域但实际上它比大多数视觉任务都更依赖对领域本质的理解对微表情心理学定义的把握、对数据标注过程的认识、对评测协议的敬畏这些甚至比刷榜技巧更重要。我读这套综述时最大的收获不是记住了某个SOTA模型的名称而是理解了为什么这个方向进展慢、卡在哪里、哪些习惯性做法是错的。对刚入门的人来说先建立这种对问题本质的感知比立刻追新模型有用得多。后面我还会继续整理这个系列的第二篇笔记重点写光流处理和深度模型复现的代码细节。