📑 本页目录(点开跳转)
模型融合与后处理
⏱ 35 分钟 | ⭐⭐ 金牌区的常规操作
🎯 一句话
融合的收益不来自「模型更强」,来自「模型们错得不一样」。所以这一章真正的主角不是加权平均的公式,而是怎么造出足够多样的模型——五个同架构同种子的模型融合,几乎等于没融。
一、模型集成的常见范式
1.1 基础融合方法
| 方法 |
说明 |
适用场景 |
| 算术平均 |
将多个模型在测试集上的概率预测值取算术平均 |
最简单且广泛使用 |
| 加权平均 |
根据模型性能差异赋予不同权重,权重需手动调优 |
模型性能差异大时 |
| 投票机制 |
多个模型对每个样本的标签进行投票,票数相同则比较概率值总和 |
多分类场景 |
| 排序平均 |
对每个模型输出的标签排名取平均排位 |
概率平均无法纠正个别分类器严重错误的场景 |
1.2 Stacking
| 维度 |
说明 |
| 原理 |
将Base分类器的概率输出作为Meta分类器的输入特征 |
| Meta分类器 |
通常选择简单模型如Logistic Regression |
| 防过拟合 |
必须用OO F(Out-of-Fold)预测作为Meta特征,避免数据泄露 |
| Blending |
Stacking的简化版:用留出法而非K折生成Meta特征,实现更简单但数据利用率低 |
1.3 概率校准
| 维度 |
说明 |
| 问题背景 |
模型输出的概率值不一定反映真实概率,融合前需校准 |
| Platt Scaling |
用逻辑回归对模型输出做校准,适合小数据集 |
| Isotonic Regression |
用保序回归做校准,适合大数据集,非参数方法 |
| 校准时机 |
融合前对每个模型独立校准,确保概率尺度一致 |
二、模型多样性保障
| 维度 |
说明 |
| 模型多样性 |
融合需要模型具有多样性,不能是同一模型同一参数 |
| 多样性来源 |
不同预训练模型(BERT/RoBERTa/DeBERTa)、不同学习率、不同随机种子、不同Fold |
| 融合收益 |
模型差异越大,融合收益越高 |
| Top方案经验 |
想要取得top成绩,必须使用多个不同模型进行融合 |
| 架构差异 > 超参差异 |
不同架构(EfficientNet+ViT)比同架构不同种子收益大 |
三、跨模型的字符级融合(Char-level Ensemble)
| 维度 |
说明 |
| 问题背景 |
不同架构的预训练大模型(如RoBERTa与DeBERTa)使用了不同的分词器,导致切分出的Token无法对齐对等融合 |
| 核心方法 |
必须利用各自附带的Offset Mapping(偏移映射) |
| 实现细节 |
将Token级别的概率精准投射回原文基于字符(Char)级别的位置上 |
| 融合方式 |
统一打分标尺后再赋予不同权重进行加权平均 |
四、Multi-Exit架构(多出口架构)
| 维度 |
说明 |
| 核心思想 |
在模型每一层都放置分类器,进行联合训练,而非仅在最后一层放置分类器 |
| 应用一(推理加速) |
浅层分类器即可对简单样本做出正确预测,提前退出推理,提升推理速度 |
| 应用二(泛化提升) |
多层分类器联合训练能有效提升模型整体泛化能力,作为上分方法使用 |
| 训练方式 |
各层分类器共享底层表征,通过联合损失函数进行端到端训练 |
五、Self-Distillation(自蒸馏)
| 维度 |
说明 |
| 核心思想 |
用同一模型的早期层输出作为教师信号指导深层训练 |
| 实现方式 |
在模型不同深度位置设置分类器,浅层输出作为软标签(Soft Labels)指导深层学习 |
| 低耗优势 |
相比传统多模型集成,自蒸馏只需训练单个模型,大幅降低计算资源消耗 |
| 适用场景 |
Code Submission赛等对推理时间和内存有严格限制的比赛 |
| 与Multi-Exit区别 |
Multi-Exit侧重联合训练多分类器,Self-Distillation侧重知识迁移和模型压缩 |
六、精细化规则后处理
6.1 通用后处理思路
| 维度 |
说明 |
| 核心方法 |
通过分析验证集上预测错误的错题本(Bad Case)制定人工干预规则 |
| 发现方式 |
通过对Bad Case的分析得出结论 |
| 实现难度 |
相对较低,主要是规则方法的添加 |
6.2 NER后处理:预测区间边界纠偏
去除硬编码偏移
| 维度 |
说明 |
| 问题背景 |
基线代码在最终输出字符区间时,会习惯性地给结果直接+1 |
| 导致后果 |
预测的起始和结束位置整体向右偏移一个字符 |
| 解决方案 |
去除这个不合理的加1操作 |
动态剥离首尾空格
| 维度 |
说明 |
| 实现方式 |
在提取预测出的区间时,增加一层循环判断 |
| 头部处理 |
如果区间开头恰好是一个空格字符,就把起始位置往右移(加1) |
| 尾部处理 |
如果区间结尾恰好是个空格,就把结束位置往左移(减1) |
| 最终效果 |
精确剔除多余的空格,直接提升准确率得分 |
七、混合词表初始化兜底策略
| 维度 |
说明 |
| 问题背景 |
使用"词频映射"手段将赛题的脱敏ID强制还原为明文时,必然会遇到部分ID映射失败的情况 |
| 原装参数与定制参数拼接 |
对于映射成功的标点符号和高频词,直接使用开源BERT强大的初始Token Embedding权重。对于映射失败的脱敏ID,不要任其随机初始化,而是把前期在无标签脱敏语料上用Gensim训练好的Word2Vec向量提取出来,进行定点替换填入 |
| 核心优势 |
这种拼图式初始化能在起步阶段最大化保留语料的共现信息 |
八、CV任务融合策略
8.1 分类任务融合
| 方法 |
说明 |
适用场景 |
| 概率平均 |
多模型预测概率取算术平均 |
通用首选 |
| 加权平均 |
按验证集表现分配权重 |
模型性能差异大时 |
| 投票法 |
多数表决选类别 |
模型数量为奇数时 |
| Stacking |
基模型概率作为元特征 |
后期冲刺 |
8.2 检测任务融合
| 方法 |
说明 |
适用场景 |
| WBF融合 |
加权融合多模型预测框 |
检测融合首选 |
| NMS融合 |
先合并所有框再NMS |
简单场景 |
| Soft-NMS融合 |
先合并再Soft-NMS |
密集目标 |
| 分层融合 |
不同尺度用不同模型,按尺度融合 |
多尺度场景 |
8.3 检测融合实战流程
1. 各模型独立预测 → 得到各自的框集合
2. 合并所有模型的框集合
3. 用WBF/NMS进行框融合
4. OOF选择最优置信度阈值
5. 过滤低置信度框
6. 输出最终结果
8.4 分割任务融合
| 方法 |
说明 |
适用场景 |
| 概率平均 |
多模型像素级概率取平均 |
通用首选 |
| 加权平均 |
按验证集IoU分配权重 |
模型差异大时 |
| Stacking |
像素级概率作为元特征 |
后期冲刺 |
九、NLP任务融合策略
| 方法 |
说明 |
效果 |
| 概率平均 |
多模型输出概率取平均再取argmax |
最简单有效 |
| 加权概率融合 |
按验证集表现分配权重 |
比简单平均更优 |
| 投票融合 |
多模型预测结果投票 |
模型差异大时效果好 |
| 特殊概率融合 |
用超参控制融合权重,非简单平均 |
上分点大,需调参 |
| Stacking |
基模型概率作为特征,元模型学习组合 |
最强但易过拟合 |
NLP融合多样性保证
| 维度 |
方法 |
| 模型多样性 |
BERT/RoBERTa/DeBERTa/MacBERT不同架构 |
| 数据多样性 |
不同折训练、不同数据增强方式 |
| 超参多样性 |
不同lr、epoch、seed |
| 输入多样性 |
不同截断策略、不同预处理 |
十、知识蒸馏(Knowledge Distillation)
| 维度 |
说明 |
| 核心思想 |
用大模型(Teacher)的软标签(Soft Label)指导小模型(Student)训练 |
| 软标签 |
Teacher输出的概率分布(经温度T的Softmax),包含类别间相似度信息 |
| 温度参数T |
T越大概率分布越平滑,通常T=2~5,传递更多暗知识 |
| 损失函数 |
L = alpha * L_hard(学生与真实标签) + (1-alpha) * L_soft(学生与教师软标签) |
| alpha取值 |
通常0.5~0.7,软标签权重不宜过低 |
| 竞赛应用 |
Code Submission赛中对大模型蒸馏到小模型,保持精度同时降低推理时间和内存 |
| 与Self-Distillation区别 |
Self-Distillation是自身不同层之间蒸馏,Knowledge Distillation是不同模型之间蒸馏 |
蒸馏实战流程
1. 训练Teacher模型(大模型,如DeBERTa XLarge)
2. 用Teacher对训练集推理,保存Soft Label(温度T=3)
3. Student模型训练时同时学习Hard Label和Soft Label
4. 调整alpha权重,平衡两种损失
5. 最终提交Student模型(小模型,如DeBERTa Base)
十一、Snapshot Ensemble(快照集成)
| 维度 |
说明 |
| 核心思想 |
单次训练中利用余弦退火调度器的周期性重启,保存每个周期末的模型快照 |
| 实现方式 |
使用CosineAnnealingWarmRestarts调度器,T_0=5~10个epoch |
| 快照数量 |
通常保存5~7个快照,相当于免费获得5~7个不同模型 |
| 融合方式 |
多个快照的预测概率取平均 |
| 优势 |
无需训练多个模型,单次训练即可获得集成效果 |
| 与多折融合区别 |
多折需要K次训练,Snapshot只需1次训练 |
| 适用场景 |
训练资源有限时,或作为融合多样性的补充来源 |
十二、特征级融合 vs 预测级融合
| 维度 |
预测级融合 |
特征级融合 |
| 融合对象 |
各模型的预测概率/标签 |
各模型的中间特征表示 |
| 实现方式 |
概率平均/投票/Stacking |
将不同模型的隐藏层向量拼接后接分类器 |
| 信息保留 |
仅保留最终预测信息 |
保留更丰富的中间表征信息 |
| 复杂度 |
低 |
高 |
| 过拟合风险 |
低 |
较高 |
| 竞赛推荐 |
通用首选 |
后期冲刺,追求极致性能时 |
特征级融合实现
1. 各模型提取倒数第二层隐藏向量
2. 将多个模型的向量拼接(concat)或相加(add)
3. 拼接后的向量接全连接层做最终分类
4. 可端到端联合训练,也可冻结各模型只训练融合层
十三、融合权重搜索方法
| 方法 |
说明 |
适用场景 |
| 等权重 |
所有模型权重相同 |
快速baseline |
| 验证集F1加权 |
权重正比于验证集F1 |
简单有效 |
| 网格搜索 |
离散化权重空间穷举 |
模型数少(2~3个)时 |
| 贝叶斯优化 |
用Optuna搜索最优权重组合 |
模型数多时 |
| Nelder-Mead |
无梯度优化方法搜索权重 |
连续权重空间 |
| Stacking自动学习 |
元模型自动学习最优组合 |
最强但易过拟合 |
权重搜索注意事项
| 维度 |
说明 |
| 权重归一化 |
所有权重之和应为1 |
| 搜索空间 |
2个模型只需搜1个权重,3个模型搜2个,维度不宜过高 |
| 验证集选择 |
用OOF预测搜索权重,避免用测试集搜索导致过拟合 |
| 单模型下限 |
融合结果不应低于最强单模型,若低于则权重分配有问题 |
🔗 这一章连到哪里
✅ 检查点
- 融合为什么有效?用一句话说清它的前提。
- 造模型多样性有哪几条路?哪条最便宜?
- 「特征级融合」和「预测级融合」的区别是什么?各适合什么场景?
- 为什么融合权重不能直接在 LB 上搜?
- Snapshot Ensemble 的巧妙之处在哪?
- 规则后处理为什么在很多赛题里是稳定的分数来源?
👀 答案
- 多个模型的错误如果不相关,平均之后误差会互相抵消。前提是「错得不一样」——🔗 这就是[偏差-方差分解]里 Var(平均) = ρσ² + (1−ρ)σ²/M 那个式子:第一项不随模型个数减小,只能靠降低相关性 ρ。
- ①不同随机种子(最便宜,改一个数字)②不同模型架构 ③不同特征子集 ④不同数据划分/采样 ⑤不同损失函数或目标 ⑥不同输入尺度/预处理。种子最便宜但多样性也最弱;不同架构多样性最强但成本最高。
- 预测级融合是把各模型的预测结果加权平均(简单、通用、不需要重训);特征级融合是把各模型的中间表示拼起来再训一个头(能学到更复杂的组合,但要重训且容易过拟合)。时间紧、模型异构 → 预测级;有充足数据和时间、想榨干最后一点 → 特征级。
- 因为 LB 只给你一个分数,你在上面搜权重等于把 LB 当成了验证集——搜出来的权重是过拟合 LB 的,私榜(Private LB)上会掉。正确做法:在 OOF 预测上搜权重。
- 一次训练里拿到多个模型。用周期性的学习率调度,每次学习率降到谷底时保存一个检查点——这些检查点落在不同的局部极小值里,天然有多样性,而训练成本只有一份。
- 因为模型学的是统计规律,而规则能编码硬约束。比如「预测值必须非负」「同一订单的多行预测必须一致」「这个类别在测试期不可能出现」——这些是模型不知道但你知道的东西。它是把领域知识补回去的最直接手段,而且通常很稳(不依赖数据分布)。
🛑 可以停在这里
⚡ 走神救援
⭐融合的收益不来自「模型更强」,来自「模型们错得不一样」——数学上就是 Var(平均) = ρσ² + (1−ρ)σ²/M,第一项不随模型数减小,只能靠降低相关性 ρ,所以五个同架构同种子的模型融合几乎等于没融。造多样性的路(从便宜到贵):不同种子 → 不同特征子集 → 不同数据划分 → 不同损失 → 不同架构。预测级融合简单通用不用重训;特征级融合更强但要重训且易过拟合。⚠️融合权重必须在 OOF 上搜,绝不能在 LB 上搜(那等于把 LB 当验证集,私榜会掉)。Snapshot Ensemble 的巧妙在于用周期性学习率一次训练拿到多个落在不同极小值的模型。规则后处理是把模型不知道而你知道的硬约束补回去(非负、行间一致性、不可能出现的类别),稳定且不依赖分布。
打卡记录保存在你的浏览器里,首页能看到总进度