多模态表情识别-超参数调试


(一)参数配置以及调试说明

一、【当前实验】实际使用的超参数一览(按模块)

当前设定配置: 这次实验真实生效的配置


1️⃣ 数据 & 训练流程超参数

超参数 当前值 位置
batch_size 8 DataLoader
gradient_accumulation_steps 4 Trainer
等效 batch size 32 8 × 4
num_epochs 12 trainer.train
train / val 比例 85% / 15% train_test_split
max_length 64 tokenizer
image_size 224 Dataset
num_workers 0 DataLoader
pin_memory True train_loader

2️⃣ 模型结构相关超参数

🔹 文本编码器(DeBERTa-large)

参数 当前设置
模型 deberta-large-mnli
hidden_size 1024
微调层数 最后 3 层 + pooler
冻结比例 80% 冻结

🔹 图像编码器(自定义 ResNet-like)

参数 当前设置
基础结构 Conv7×7 + 4 stage
最终输出维度 512
全局池化 AdaptiveAvgPool
Dropout 0.3

🔹 融合层 & 注意力

模块 当前值
unified_dim 256
cross-attention heads 4
attention dropout 0.2
fusion MLP depth 2 层
residual projection 启用

3️⃣ 优化器 & 学习率策略

参数 当前值
optimizer AdamW
learning_rate 2e-5
weight_decay 0.01
betas (0.9, 0.999)
grad_clip 1.0
loss 加权 CrossEntropy
class_weight 动态估计(最多 1000 样本)

🔹 Scheduler

参数 当前值
scheduler Cosine + Warmup
warmup_steps 1 epoch
total_steps 12 epochs
LR decay cosine

🔹 早停 & 调参策略

参数 当前值
patience 6
improvement_threshold 0.001
lr decay trigger patience // 2
lr decay factor 0.5

二、【推荐配置】——分“算力 / 数据规模”给结论

下面是我结合当前模型复杂度 + Apple MPS 实际表现给的实用建议。


🔥 推荐配置 A(当前代码的「最优稳健版」)

适合:中等数据量(5k–30k),单卡 / MPS

batch_size: 8
gradient_accumulation_steps: 4   # 等效32
learning_rate: 2e-5
num_epochs: 10~12
max_length: 64
image_size: 224
unified_dim: 256
dropout: 0.3
warmup_ratio: 0.08

✔ 现在基本 100% 符合这个推荐配置


🚀 推荐配置 B(追求更高上限)

前提:数据量 > 20k,且不 OOM

batch_size: 12
grad_accum: 4      # 等效48
learning_rate: 1.5e-5
num_epochs: 15
unified_dim: 384
cross_attention_heads: 6
dropout: 0.25

📈 通常 F1 +0.5 ~ +1.2


⚠️ 推荐配置 C(小数据防过拟合)

batch_size: 6
grad_accum: 4
learning_rate: 1e-5
num_epochs: 8
dropout: 0.4
freeze_text_layers: all but last 2

三、【一般怎么调?】——一套“工程师可复用”的调参顺序

这是建议以后固定采用的流程


🧠 Step 1:先锁定结构,别乱动

先不动的参数:

  • 模型结构
  • cross-attention 机制
  • unified_dim
  • 图像 backbone

👉 否则在“调超参数”其实是在“调模型”


🔥 Step 2:只动 3 个核心旋钮

🎯 ① 学习率(最重要)

现象 调整
loss 不降 lr × 1.5
val F1 抖动 lr × 0.7
早期过拟合 lr × 0.5

经验范围:

DeBERTa-large 微调安全区间:
1e-5 ~ 3e-5

🎯 ② 等效 batch size

effective_bs = batch_size × grad_accum
数据规模 推荐
<5k 16–24
5k–20k 32
>20k 48–64

🎯 ③ dropout(多模态极其关键)

现象 调整
训练 F1 高,验证低 ↑ dropout
收敛慢 ↓ dropout
类别塌缩 ↑ dropout

🧪 Step 3:再考虑这些“二级参数”

优先级从高到低:

  1. warmup_steps(5–10%)
  2. 冻结/解冻文本层数
  3. class_weight 平滑
  4. early stopping patience

这是一个非常关键、而且“像研究者”的问题
我会按“这份代码已经具备的工程条件”来回答,而不是泛泛而谈。

核心思想一句话:
调超参数 ≠ 看一次准确率,而是做“受控对比 + 稳定性验证”


(二)调试验证对比

一、当前代码「已经具备」哪些验证条件?

好的地方:
现在的工程代码 已经天然支持严谨实验验证,包括:

✅ 固定随机种子(train_test_split random_state=42)
✅ 明确的 val set(非 test)
✅ 保存 best_val_f1
✅ 训练曲线(loss / f1 / acc)
✅ 类别分布与置信度统计
✅ early stopping
✅ 可重复训练(本地模型 + 固定数据)

👉 所以缺的不是“功能”,而是方法论


二、验证超参数效果的「三层验证框架」

建议以后固定使用这三层,几乎就是论文级流程可支持报告文档内容。


🧪 第一层:单变量受控实验(最重要)

一次只改一个超参数

🔬 标准流程(现在就能做)

Baseline(当前代码)
↓
只改 learning_rate
↓
只改 dropout
↓
只改 effective batch size

📊 每次必须记录 6 个指标

指标 从哪里来
best_val_f1 trainer.best_val_f1
best_val_acc trainer.best_val_acc
收敛 epoch early stop epoch
train-val gap 曲线观察
预测分布 final_counts
置信度均值 confidence_scores.mean

🧠 示例:验证 learning_rate 是否更好

实验 lr best val F1 收敛 epoch
baseline 2e-5 0.734 8
exp-1 1.5e-5 0.751 10
exp-2 3e-5 0.702 5

📌 结论写法(报告用)

学习率 1.5e-5 在验证集上取得更高 F1,并表现出更稳定的收敛过程。


📈 第二层:稳定性验证(防“偶然性”)

这是90% 学生不会做,但老师一看就加分的点

做法(非常简单)

同一套超参数,换随机种子跑 3 次

for seed in [42, 2023, 2025]:
    train_test_split(..., random_state=seed)

验证指标

指标 解释
F1 mean 平均性能
F1 std 稳定性
最差 F1 风险评估

🧠 示例表格

配置 F1(mean) F1(std)
baseline 0.732 0.021
tuned 0.748 0.009

📌 关键结论

调参不仅提升平均性能,同时显著降低性能波动。


⚖️ 第三层:行为一致性验证(多模态特有)

这是多模态实验的“隐性评分点”

代码里已经算了:

  • 预测分布
  • 置信度
  • neutral 比例

必须对比的 3 个行为指标

行为 为什么重要
类别塌缩是否缓解 防止模型作弊
neutral 是否恢复 多模态核心
低置信度样本比例 校准质量

🧠 示例对比

指标 baseline tuned
neutral 比例 4.2% 14.6%
mean confidence 0.91 0.83
low-conf samples 6% 18%

📌 解释(非常加分)

调整后模型预测更加保守,置信度分布更合理,减少了过度自信问题。


三、「应该怎么写结论」才像科研?

给一个直接可用模板


✅ 超参数验证结论模板

在保持模型结构不变的前提下,我们对学习率、等效 batch size 与 dropout 进行了受控超参数调优。
实验结果表明,适度降低学习率并增加正则化强度可以有效提升验证集 F1,并改善模型预测分布的稳定性。
同时,多次随机种子实验表明,该配置在性能和稳定性上均优于 baseline。


四、这套代码「可以立刻加的两个小改动」(强烈推荐)

🔧 1️⃣ 自动实验日志(5 行代码)

results['hyperparameters']['experiment_name'] = 'lr_1.5e-5_dropout_0.3'

每次调参改名字,后面自动对比。


🔧 2️⃣ 保存 val 预测(用于错误分析)

val_preds_file = f"val_preds_{timestamp}.csv"
pd.DataFrame({
    'guid': val_guids,
    'true': all_labels,
    'pred': all_preds
}).to_csv(val_preds_file, index=False)

👉 老师/评委最喜欢看到:能“解释错误样本”。


五、「专业级建议」

超参数好坏,不在于“跑没跑分”,而在于:

  • 是否可复现
  • 是否稳定
  • 是否行为合理
  • 是否有对照

现在这套代码,已经完全能支撑一篇“严谨实验报告”


posted @ 2026-01-27 03:45  kkman2000  阅读(46)  评论(0)    收藏  举报