Skip to content

zuowen7/emotion-recognition

Repository files navigation

RAVDESS 多模态情感识别系统

项目简介

本项目在 RAVDESS 数据集上构建了多模态(音视频)情感识别融合网络。针对小样本多模态任务中常见的 I/O 拥堵、特征维度不匹配、以及严重的"身份泄露 (Identity Leakage)"导致过拟合等痛点,从底层数据管线和网络架构两个维度进行了深度优化。

在严格的 Subject-Independent 5 折交叉验证下,系统最终达到了 66.56% ± 4.28% 的平均验证准确率,最高单折达到 70.38%,触碰到了冻结非情感专用预训练特征的物理天花板。

数据集

  • RAVDESS (Ryerson Audio-Visual Database of Emotional Speech and Song)
  • 24名专业演员(12男12女)
  • 8类情绪:平静、开心、悲伤、愤怒、恐惧、厌恶、惊讶、中性
  • 两个不同的情感强度
  • 约4900个音视频样本

评估协议

采用基于 actor_id 的 5 折分组交叉验证 (GroupKFold),确保验证集中的演员在训练集中处于绝对不可见状态。这是衡量模型真正泛化能力的试金石。

五折交叉验证结果

Fold 验证集演员 验证准确率
Fold 1 2, 9, 14, 19, 24 69.13%
Fold 2 3, 4, 13, 17, 23 58.65%
Fold 3 1, 7, 12, 16, 22 69.13%
Fold 4 6, 8, 11, 18, 21 70.38%
Fold 5 5, 10, 15, 20 65.50%
平均 - 66.56% ± 4.28%

5折交叉验证结果

技术细节与踩坑记录

问题1:特征提取速度瓶颈

现象 使用 MTCNN 进行人脸检测时,采用常规的逐帧三阶段检测(P-Net → R-Net → O-Net),提取速度仅为 1.02 it/s。处理一个视频需要几分钟,无法支撑高频的模型迭代。

分析 RAVDESS 数据集是固定机位录制的,演员面部在全局坐标系中的绝对位移极小。逐帧检测产生了大量冗余计算。

解决方案 引入数据集的"物理先验"约束:

  • 将检测策略从"逐帧检测"降维为"单帧锚定 + 全局复用"
  • 仅在关键帧计算 Bounding Box 的空间坐标
  • 在时序维度上利用 NumPy 内存切片与 GPU F.interpolate 向量化操作完成裁剪

收益 预处理提速 20倍以上,且无损保留了面部肌肉运动的时序动态信息。


问题2:I/O Bound 导致 GPU 空转

现象 模型训练初期,4900 余个独立的 .pt 特征文件引发严重的 I/O Bound:

  • CPU 满载
  • GPU 利用率不足 30%
  • 单 Epoch 耗时过长

尝试与失败 尝试将 3.2GB 全量数据载入内存缓存,但因多进程 (num_workers>0) 的数据复制机制触发严重的 OOM (Out of Memory)。

解决方案

  1. OS 级共享内存 (share_memory_)

    • 在 Dataset 初始化时,将载入的 Tensor 显式声明为共享内存对象
    • 使其驻留在 /dev/shm 内存段中
    • 开启多个 DataLoader Worker 时,子进程仅需获取内存指针进行零拷贝读取
    • 彻底解决了 OOM 危机
  2. CUDA 异步预取 (CUDAPrefetcher)

    • 在 PyTorch 的标准数据流之外,构建独立 CUDA Stream
    • GPU 执行当前 Batch 矩阵运算的同时,后台异步将下一个 Batch 通过 DMA 直传至显存

收益 I/O 耗时趋近于 0,GPU 算力得以 100% 释放,单 Epoch 耗时压缩至秒级。


问题3:身份泄露 (Identity Leakage) 导致过拟合

现象 在多模态融合网络 (Cross-Attention) 的初步训练中,出现极端的过拟合:

  • 训练集准确率迅速攀升至 100%
  • 验证集准确率停滞在 50%-57% 区间

根本原因 预训练大模型提取的特征存在严重的领域偏差 (Domain Gap):

  • VGGFace2 的优化目标是区分不同个体的身份,其输出的 512 维特征本质上是高度浓缩的"身份编码"
  • Wav2Vec2.0 保留了极强的个人声纹与音色特征

在约 4900 样本的小数据集上,后端融合网络的高维参数量 (~727K) 使模型轻易走上了"捷径":通过死记硬背训练集演员的面部特征与声纹特征来进行分类,而非学习泛化性强的情感动态特征。


解决方案:物理层去身份化

1. 实例归一化 (Instance Normalization)

对单个样本的时间序列特征应用归一化:

$$x_{norm} = \frac{x - \mu}{\sigma}$$

减去时间维度的均值 $\mu$,从数学层面抹除静态的"平均人脸"与"基础音色"等绝对身份信息。

2. 差分特征提取 (Delta Features)

计算相邻帧的特征差值:

$$x_{delta} = x_t - x_{t-1}$$

过滤掉冗余的静态背景信息,使网络输入纯粹的"特征变化率"(运动向量),引导注意力机制 (Attention) 聚焦于情感的演进过程。

3. 架构层面的正则化策略

  • 动态位置编码与 Padding Mask

    • 修复变长音频序列中的"幽灵 Bias"污染问题
    • 确保 Attention 计算严格忽略 Padding 区域,保证特征表达的纯净度
  • 局部时序先验 (Temporal Convolution)

    • 在全局 Cross-Attention 前插入轻量级 1D 卷积
    • 提取局部表情变化的"加速度"
    • 弥补全局注意力对相邻时序依赖较弱的缺陷
  • 多模态 Mixup (Multimodal Mixup)

    • 训练时以 50% 概率对不同样本的音视频特征及标签进行线性插值混合
    • 特别地,针对变长序列的 Mask 矩阵采用了逻辑与 (&) 合并,确保混合序列有效信号的完整性
  • Focal Loss

    • $\gamma=2.0$, Label Smoothing=0.1
    • 应对数据集中细分情绪(如 Neutral 仅有单一强度)带来的难易样本不均衡问题

收益 成功将模型的训练集准确率压制在合理区间(避免了 100% 的死记硬背),并将 5 折交叉验证的平均准确率大幅提升至 66.56%,最高单折达到 70.38%


消融实验与分析

为了验证各优化模块的实际贡献,设计了详细的消融实验:

模型版本 核心模块 5折平均验证准确率 现象分析
Baseline 基础 Cross-Attention ≈52.0% 极度过拟合,模型深陷"身份泄露",依赖静态人脸进行分类
+去身份化 +实例归一化 & 差分特征 ≈60.5% 成功剥离绝对身份特征,模型开始关注动态变化率,跨演员泛化能力实现质变
+局部时序 +Temporal Conv ≈63.8% TCN 弥补了全局 Attention 缺乏局部感受野的缺陷,有效捕捉表情的短时"加速度"
+极致正则 (Ours) +Multimodal Mixup & Dropout 66.56% Mixup 强制模型学习混合特征分布,彻底打破训练集记忆效应,达到当前特征空间的泛化极限

关键发现 实验清晰地表明,针对小样本多模态任务,单纯增加网络深度毫无意义。最大的性能飞跃 (+8.5%) 来自于物理层面的去身份化。这反向证明了:在使用非情感领域预训练大模型时,消除 Domain Gap 的优先级远高于融合策略的复杂设计。


技术方案

特征提取

特征提取

  • 视觉特征:InceptionResnetV1(基于 VGGFace2 预训练,512维)
  • 音频特征:Wav2Vec2.0(基于语音识别语料预训练)

系统级工程优化

I/O 优化:从 1.02 it/s 到可用状态

  • 引入数据集的"物理先验"约束
  • 检测策略从"逐帧检测"降维为"单帧锚定 + 全局复用"
  • 预处理提速 20倍以上

内存优化:解决 I/O Bound 和 OOM

  • OS 级共享内存 (share_memory_):零拷贝读取,解决 OOM 危机
  • CUDA 异步预取 (CUDAPrefetcher):DMA 直传至显存
  • GPU 算力 100% 释放,单 Epoch 耗时压缩至秒级

核心算法:去身份化 (De-identification)

针对预训练模型的身份偏差问题,实施了多层次的"去身份化"策略:

1. 实例归一化 (Instance Normalization)

对单个样本的时间序列特征应用归一化,从数学层面抹除静态的"平均人脸"与"基础音色"等绝对身份信息。

2. 差分特征提取 (Delta Features)

计算相邻帧的特征差值,过滤掉冗余的静态背景信息,使网络输入纯粹的"特征变化率",引导 Attention 聚焦于情感的演进过程。

3. 架构层面的正则化

  • 动态位置编码与 Padding Mask:修复变长音频序列中的"幽灵 Bias"污染
  • 局部时序先验 (Temporal Convolution):提取局部表情变化的"加速度"
  • 多模态 Mixup:训练时以 50% 概率混合不同样本的特征及标签

网络架构与超参数

  • 融合网络:Cross-Attention 架构
  • 隐层维度:d_model = 128
  • 参数量:727.4K
  • 正则化:Dropout = 0.5,高斯特征噪声 = 0.05,Mixup α = 0.4
  • 优化器:AdamW(权重衰减 10^-2)+ 余弦退火学习率调度
  • 损失函数:Focal Loss(γ = 2.0, Label Smoothing = 0.1)

实验环境

  • 计算平台:Kaggle 容器环境
  • GPU:双 NVIDIA T4 (16GB x 2)
  • 系统 RAM:30GB
  • 加速机制:PyTorch 混合精度训练 + CUDAPrefetcher

消融实验

模型版本 核心模块 5折平均验证准确率
Baseline 基础 Cross-Attention ≈52.0%
+去身份化 +实例归一化 & 差分特征 ≈60.5%
+局部时序 +Temporal Conv ≈63.8%
+极致正则 (Ours) +Multimodal Mixup & Dropout 66.56%

最大的性能飞跃 (+8.5%) 来自于物理层面的去身份化。这证明了在使用非情感领域预训练大模型时,消除 Domain Gap 的优先级远高于融合策略的复杂设计。

优化路径

项目经历了典型的"发现瓶颈 → 击碎瓶颈"演进路径:

  • Phase 1: I/O 阻塞期 → OS 共享内存 + CUDA 预取流,I/O 耗时趋近于 0
  • Phase 2: 记忆过拟合期 → 参数量裁剪 + 高斯噪声 + Dropout,验证集爬升至 58%
  • Phase 3: 身份泄露期 → 物理层去身份化 + Mixup,最终定格在 66.56%

训练曲线

Fold 4 训练曲线

从训练曲线可以观察到,引入时序遮蔽与实例归一化后,训练集准确率被压制在 90%-95% 区间。这种在训练集上的"挣扎",换来了验证集准确率突破 60% 的鲁棒性。

局限性与未来工作

当前局限

现有系统的核心局限在于上游特征提取阶段的信息折损。VGGFace2 和 Wav2Vec2.0 的优化目标与情感无关,诸多细微的情感语义在特征提取时已被当作"噪声"丢弃。

未来方向

  1. 特征提取器替换:引入专为情感计算预训练的基座模型(如 EfficientFace 处理视觉,emotion2vec 处理音频),从源头上提高情感信噪比

  2. 端到端微调 (PEFT):采用 LoRA (Low-Rank Adaptation) 等参数高效微调技术,将后端融合网络的梯度回传至前端大模型,实现端到端的表征空间对齐与重构

项目结构

.
├── 预处理.ipynb              # 数据预处理和特征提取
├── notebookad0322.ipynb      # 模型训练和评估
├── 5_Fold_Results.png        # 五折交叉验证结果可视化
├── Fold_1_Curve.png          # Fold 1 训练曲线
├── Fold_2_Curve.png          # Fold 2 训练曲线
├── Fold_3_Curve.png          # Fold 3 训练曲线
├── Fold_4_Curve.png          # Fold 4 训练曲线
├── Fold_5_Curve.png          # Fold 5 训练曲线
└── README.md                 # 项目说明文档

技术博客

完整的技术细节和踩坑记录:

致谢

  • RAVDESS 数据集由 Ryerson University 提供
  • 预训练模型来自 VGGFace2 和 Facebook AI Research (Wav2Vec2.0)

License

MIT License


如果本项目对你的研究或工作有帮助,欢迎点个 ⭐ Star!

About

基于RAVDESS数据集的多模态情感识别系统,融合视频和音频特征,通过去身份化策略解决预训练模型的身份偏差问题,在严格的 跨演员验证协议下达到66.56%准确率

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors