模型在训练集上表现很好,到了真实用户数据却突然失灵;团队清洗了几千条标签,指标几乎没有变化;一个预训练模型在小数据集上提升明显,换到另一个领域反而不如从头训练。遇到这些情况,继续堆模型通常不是最有效的动作,因为问题已经不只发生在网络结构里。
这一章讨论机器学习项目更接近真实世界的一面:数据来自哪里,开发集代表谁,误差差距怎样拆解,标签错误该先查哪一部分,以及迁移学习、多任务学习和端到端学习分别在什么条件下值得尝试。重点不是记住几条经验规则,而是学会用一组对照数据把不同原因分开。

本章里的“目标分布”指模型上线后真正要服务的数据,而不是手头数量最多、最方便获得的数据。开发集负责指导选择,测试集负责给最终方案做一次相对独立的估计;这两个集合都应尽可能贴近目标分布。
如果训练、开发、测试样本都来自同一稳定分布,很多诊断只需要比较训练误差和开发误差。现实项目常常没有这么整齐。比如我们要识别用户手机上传的商品照片,但手里最多的是棚拍图;要检测线上支付风险,却只有几个月前的历史数据;要做低资源医学影像分类,训练样本主要来自另一种设备。
这时,简单地把所有数据混在一起再随机切分,可能得到一个数值稳定却方向错误的开发集。假设有 20 万张棚拍图、1 万张用户手机图。全部混合后随机切分,开发集大约 95% 仍是棚拍图。团队会不断优化最常见的那部分样本,但产品真正面对的是手机图。
更实用的划分是让职责服从决策目标:
训练-开发集(train-dev set)不是第二个调参集。它从训练数据来源中留出,和训练集尽量同分布,但不参与训练。它的价值是增加一个对照:当模型从训练集走向未见过的同分布样本时损失多少,再从训练来源走向目标来源时额外损失多少。
开发集和测试集应来自同一个目标定义。这里的“同一个”不要求逐条样本一模一样,而是采样人群、时间范围、设备类型、标签规则和关键切片比例要一致。否则开发集选择出的模型与测试集衡量的目标不同,最终落差无法解释。
“同分布”不能只看类别比例。若同一用户、同一视频或同一患者的相邻样本被拆到不同集合,模型可能借助实体特征取得虚高分数。带时间演化的任务还应考虑按时间切分:用过去训练,用更晚的数据开发和测试,才更接近上线后的信息边界。
目标数据少时,也不要把它全部塞进训练集。开发集太小会让方案排序受随机波动支配,测试集太小则无法估计关键切片。先根据决策需要保留评估样本,再把剩余目标样本与其他来源一起用于训练。
有了四份数据,我们就能把一条笼统的“开发集表现不好”拆成几段差距。为了讲清思路,先假设各集合使用同一损失或同一阈值下的错误率,并有一个可比较的参考水平 。参考水平可以来自合格人工、强基线或业务可达到的估计,但它不是永远准确的“贝叶斯误差”。
令训练、训练-开发和开发误差分别为 、 与 ,可以构造三段诊断量:

大,说明模型连训练来源中的可学模式都没有充分拟合,优先检查优化、容量、输入信息和训练标签质量。 大,说明模型从已见训练样本走到同来源新样本时明显退化,通常要检查过拟合、数据泄漏、有效样本量与正则化。 大,则说明从训练来源切换到目标来源产生了额外损失。
下面这组假设数值能说明差别:
这些差值是方向提示,不是统计显著性检验。样本量很小时,1 个百分点可能只是抽样波动;不同集合标签难度不同时,误差也不能机械相减。实际决策前,至少应报告样本数、置信区间或重复抽样结果,并在关键切片上复查差距是否稳定。
如果人工标注者看到的信息比模型多,人工误差就不是公平参考。例如医生同时读取影像与完整病历,而模型只拿到一张影像。反过来,人工测量流程不稳定,也可能高估任务固有难度。使用参考水平前,应明确双方输入、标签规则和评估单位是否一致。
旧式经验常说“深度网络对少量随机错标很鲁棒,因此训练集错标可以不管”。这句话容易让人误判。高容量网络能把随机标签拟合到接近零训练误差,说明它们并不会自动忽略噪声;是否清洗要看错误比例、错误结构、样本难度、业务代价和训练流程,不能套一个固定阈值。
标签问题至少分三类:

开发集和测试集的标签错误会直接改变方案排序。如果两个模型真实差距只有 0.3 个百分点,而评估集里有大量未处理的含糊或错误标签,团队可能在噪声中选模型。因此应先让开发集与测试集使用一致、可复查的标签规则。
一个可靠的审计流程可以这样做:
只查看模型判错样本会产生选择偏差。模型预测与错误标签恰好一致时,样本看起来是“预测正确”,却仍会污染评估;模型也可能靠数据泄漏碰巧猜中错误标签。随机审计提供对整体错误率更可靠的估计。
训练集是否值得全面清洗,要算机会成本。若错误高度集中在一个标注来源,定向重标通常很划算;若训练集数千万条、错误率低而且近似随机,先改损失、抽样或数据源可能更省预算。医疗、安全和合规任务中,少量系统性错标也可能不能接受,因为平均指标掩盖不了高代价切片。
不要让模型预测直接覆盖“真值”。模型可以帮助筛出疑似问题,但最终复核要有独立证据和明确规则。否则新数据集会逐步复制现有模型的偏差,后续评估也会失去独立性。
训练和目标阶段的联合分布不同时,可以统一写成:
但这条式子没有告诉我们变化发生在哪里。不同变化需要不同证据和处理方式。

协变量偏移指输入分布变化,而给定输入后的标签规律近似不变:
棚拍图换成手机图、白天摄像头换成夜间摄像头,常被当作这类问题的近似例子。可以尝试收集目标输入、让增强模拟成像条件、重采样或做重要性加权。但重要性加权依赖密度比估计,训练分布没有覆盖的目标区域无法靠加权凭空补出来。
标签先验偏移指类别比例变化,而每个类别内部生成输入的方式近似稳定:
例如疾病流行率或欺诈比例变化。模型排序能力可能仍在,但概率校准和决策阈值会受到影响。处理时要估计目标先验,并重新检查校准、阈值和成本,而不是只补一些图像增强。
概念偏移指同一个输入对应标签的规律改变:
欺诈者改变策略、政策重新定义违规、用户语言习惯变化,都可能让旧决策边界失效。只让输入看起来更像目标域通常不够,需要新标签、时间监控和再训练机制。
在干净音频上叠加办公室噪声,可能改善办公室场景;但如果真实问题来自麦克风削波、说话距离和压缩编码,仅加白噪声不会重现关键机制。合成数据的质量取决于它是否覆盖目标变化的因果路径,而不是生成了多少文件。
最直接的检查是做切片对照:真实目标样本在哪些条件下失败,增强是否真的改变这些条件,训练后对应切片是否改善,其他切片是否退化。若增强样本一眼就能被模型识别为“合成域”,还可能引入新的捷径。
迁移学习先在源任务上学习表示,再把部分或全部参数用于目标任务。以图像网络为例,较低层往往捕捉边缘、颜色和局部纹理,较高层逐渐针对源任务类别形成专用组合。Yosinski 等人的实验表明,特征可迁移性会随源任务与目标任务距离增大而下降,高层特征通常比低层更专用。

常见做法有两种:
当前 PyTorch 官方教程仍用这两种方案讲解迁移学习。代码应使用权重枚举,而不是旧的 pretrained=True:
import torch.nn as nn
from torchvision.models import resnet50, ResNet50_Weights
model = resnet50(weights=ResNet50_Weights.DEFAULT)
for parameter in model.parameters():
parameter.requires_grad = False
in_features = model.fc.in_features
model.fc = nn.Linear(in_features, 2)若要微调,可以先只训练新头,再逐步解冻后部模块,并给预训练层更小学习率:
for parameter in model.layer4.parameters():
parameter.requires_grad = True
optimizer = torch.optim.AdamW([
{"params": model.fc.parameters(), "lr": 3e-4},
{"params": model.layer4.parameters(), "lr": 3e-5},
], weight_decay=1e-4)这段代码只是结构示意,真实项目还要处理归一化层状态、数据预处理与预训练权重要求的一致性。冻结参数不等于自动冻结 Batch Normalization 的运行统计;调用 train() 时,BN 仍可能更新 running mean 和 running variance。小批量目标数据下要明确决定哪些模块处于训练模式。
迁移学习更可能在以下条件下有效:源任务数据足够多;源目标输入和表征有共享结构;目标样本不足以稳定地从头学习;预训练过程没有带来无法接受的偏差。最稳妥的做法不是凭领域名称判断,而是设置三条基线:从头训练、冻结主干、完整或分阶段微调,并在相同验证协议下比较。
负迁移也很真实。自然图像预训练不一定适合某些遥感波段、显微信号或非图像传感器;源数据中的捷径可能被一并带入。若冻结方案很差、微调仍无改善,应检查输入归一化、目标分辨率、预训练标签与目标机制,而不是继续盲目减小学习率。
迁移学习通常先学源任务、再学目标任务;多任务学习则在同一训练阶段并行优化多个相关任务。经典定义强调共享表示:一个任务的监督信号成为另一个任务的归纳偏置,帮助模型优先学习多个任务共同需要的结构。

设样本 在任务 上的损失是 , 表示该标签是否存在, 是任务权重,一个带缺失标签掩码的目标可以写成:
掩码很重要。自动驾驶图片可能只标了车道线,没有完整标注行人;“没有标签”不能直接当成“负类”。分母按有效标签数归一化,可以避免某个任务只因标注更多就主导损失。
共享结构不一定是“所有层全部共用”。常见设计包括共享主干加独立任务头、只共享低层、通过适配器进行软共享,或让部分任务有独立分支。设计边界应服从任务相关性:边缘与纹理可能共享,细粒度决策边界未必共享。
如果任务不相关、数据规模悬殊或梯度长期相互冲突,共享参数会把一个任务拖向另一个任务不合适的方向。平均损失下降也可能掩盖小任务退化。因此要分别报告每个任务的指标,并与“各自单独训练”的基线比较。
任务权重不是装饰。不同损失的数值尺度可能相差几个数量级,直接相加会让尺度大的任务取得更大梯度。可以先做归一化和人工权重基线,再根据验证证据尝试动态加权;无论方法多复杂,都要检查每个任务的实际收益与成本。
端到端学习让一个可训练系统直接从原始或接近原始的输入映射到最终输出,并联合优化总体目标。语音识别可以从声学序列预测文字,机器翻译可以从源语言序列生成目标语言序列。Deep Speech 2 展示了端到端方法在英语和普通话语音识别中的可行性,但它的成功同时依赖大规模数据、计算基础设施和完整工程系统。

端到端不等于“系统里只能有一个神经网络”,也不等于“完全不用先验”。分词、解码约束、检索模块、安全规则和后处理仍可能存在。更准确的判断是:哪些中间接口由人工固定,哪些模块能被最终目标的梯度联合优化。
端到端方案适合输入到输出之间有足够配对数据、中间表示难以手工定义、最终目标可微或能稳定优化的场景。联合训练减少了人为接口造成的信息瓶颈,也可能让模型学到传统流水线忽略的表示。
但代价同样具体:
人脸身份识别是一个直观例子。直接把整张街景映射到身份,需要模型同时学习人脸检测、对齐、质量判断和身份表示。若检测与身份数据分别很丰富,先检测再识别往往更容易训练和诊断。后来也可以对部分模块联合微调,这是一种混合方案,不必在“纯流水线”和“纯端到端”之间二选一。
是否端到端,最好被当作可比较的系统设计假设。先建立模块化基线,再比较联合优化能否稳定提升最终指标,同时记录训练数据需求、诊断成本、推理延迟与失败恢复方式。
迁移学习、多任务学习和端到端学习经常被放在同一页,却解决不同问题。选择前先问“我缺的是什么”:目标数据不足时,迁移学习借用其他数据学到的表示;多个相关任务同时存在时,多任务学习利用并行监督;人工流水线接口限制总体效果且端到端配对数据充足时,联合优化才可能带来收益。
这三者也可以组合。一个预训练主干可以在多个目标任务上做多任务微调;一个端到端语音系统也可以增加音素或说话人属性作为辅助任务。组合越复杂,越要保留逐步基线,否则最终只知道“大系统有效”,不知道收益来自哪里。
项目常把“同属医疗”“都是文本”当作任务相关性的证据,这远远不够。更有用的证据包括:输入统计是否相近,低层特征是否可复用,标签边界是否冲突,源模型在目标切片上的线性探测结果,以及微调时哪些层改变最大。
当目标数据很少,可以先冻结主干做线性探测;若线性头已明显优于从头训练,说明现有表示包含可用信息。再逐层解冻,观察收益是否超过方差和训练成本。多任务同样可以先共享较少层,再根据各任务验证结果扩展共享范围。
策略真正落地时,不需要一份几十页报告。一张实验单就能迫使团队说明:当前观察是什么,最可能的原因是什么,哪项证据能推翻这个判断,以及预算花完后怎样决定保留或放弃。
可以按下面顺序填写:
写清目标分布、预测单位、时间边界和主要指标。若这些定义改变,新的结果不能与旧实验直接混为一谈。
记录训练、训练-开发、开发和关键切片的误差与样本量,标出最大的稳定差距。
抽样复核失败案例和随机案例,区分标签问题、输入覆盖不足、概念变化与模型能力问题。
选择能直接作用于主要差距的最小实验,并写出保持不变的数据版本、评估脚本和阈值策略。
假设诊断显示 最大,而且错误集中在夜间手机图。一个可证伪实验是:“在不改变模型与阈值的条件下,加入能模拟真实曝光和压缩机制的增强;若夜间切片召回提升至少 2 个百分点,整体误报率不增加超过 0.2 个百分点,就保留。”这比“多做点增强看看”更容易比较,也更容易失败得有价值。
上线后还要继续维护这张图。输入统计变化只能提示风险,不能证明性能已经下降;真正的概念偏移需要新标签或可信代理指标。监控应同时覆盖输入质量、预测分布、关键切片、延迟和延迟到达的真实标签。报警后先确认采集或日志是否变化,再决定重校准、重训还是回滚。
在运行前写下采用条件、停止条件和副作用检查;结果出来后记录证据,而不是只保留最好分数。