2019年,MIT的研究团队发布了一个工具包,叫Cleanlab。我不是来打广告的——我是被它救过。那年我做一个图像分类项目,模型在验证集上明明有95%的准确率,但一上线就掉到80%。我以为是过拟合,调了半个月,一点用没有。后来有个朋友随口说了一句:“你确认过验证集的标签是准的吗?”我当场愣住了。等我真的去查,才发现验证集里有5%的标签是错的。而训练集里的错误率更高,大约8%。模型一直在努力记住这些错误标签——它不是在学知识,是在背错题。从那天起,我养成了一个习惯:动手训练之前,先怀疑数据。

你可能觉得,标注错误是少数,是脏数据而已。但一查文献吓一跳:CIFAR-10测试集有约5.8%的错误标注,ImageNet也有5.8%,甚至MNIST都有0.3%(Pervasive Label Errors in Test Sets)。这些是全世界最常用的基准数据集,无数论文的结果都建立在它们上面。而你的数据,大概率比这些更脏。数据去噪这件事,重要性被严重低估了。
为什么模型自己不能发现错误?先说一个错误直觉
最简单的思路是:训练一个模型,看它在每个样本上的损失。损失大的就是错误。听起来有理,但实际不行。因为模型在训练中会逐渐记住错误的标签——它把“错误”当成了“正确”来学。等训练结束,那个错误样本的损失可能很小。也就是说,你拿一个已经被污染过的模型来当裁判,它自然会包庇那些污染源。我最早就是这么干的,结果错误检测的准确率跟抛硬币差不多。后来我明白了:需要用“样本外”的预测,而不是模型在自己训练集上的预测。什么是样本外?就是用一个从未见过这个样本的模型来预测它。怎么做?交叉验证。
置信学习:让模型“举报”自己的训练数据
置信学习(Confident Learning)的核心思想不复杂。把训练数据分成K折,用K-1折训练模型,预测剩余1折。这样每个样本都拿到一个来自“没有见过它”的模型的预测概率。然后你可以做一件事:比较给定标签和预测概率,找出那些“模型很自信地认为应该是另一个类,但标签却是这个类”的样本。
这里有个关键细节:阈值怎么定?如果你用一个统一的阈值(比如概率小于0.5就认为错误),会被类别不平衡问题搞死。置信学习的方法更聪明:它先估计出噪声标签和真实标签的联合分布,再从这个分布反推出哪些样本最有可能是被标错的。这篇论文是Curtis Northcutt等人在2019年发表的《Confident Learning: Estimating Uncertainty in Dataset Labels》(论文链接)。简单说,它构建了一个“标签噪声矩阵”,每一格表示“真实类别是i,但被标注成j”的样本数量。然后对每个样本计算一个置信度阈值,阈值不是固定值,而是每个特征组内的平均值,从而让算法能处理不同类别的不同难度。
如果你不想深入数学,直接使用Cleanlab库(官方文档)就行。做法是三步:
- 对训练集做K折交叉验证,得到每个样本的样本外预测概率矩阵。
- 调用CleanLearning的fit方法,自动估计出噪声标签的候选集合。
- 对候选样本按置信度排序,决定是删除、纠正还是重新标注。
代码大概长这样:
from cleanlab.classification import CleanLearning
cl = CleanLearning(model) # 你的模型
cl.fit(X_train, y_train)
issues = cl.get_label_issues()
print(issues['is_label_issue'].mean()) # 噪声占比
suspect_ids = issues.index[issues['is_label_issue']].tolist()
清理不只是删除:三种策略
找到错误标注之后,有三个选择,各有适用场景。
| 策略 | 做法 | 适用场景 | 风险 |
|---|---|---|---|
| 删除 | 直接移除被判为错误标注的样本 | 错误率较高,数据量大 | 可能误删一些难样本,导致模型在边界上退化 |
| 纠正 | 用模型预测的高置信类别或人工审核后的标签替换 | 错误样本数量有限,人工成本可控 | 如果替换标签来自同一模型,可能继承模型的偏见 |
| 重新加权 | 在损失函数中降低噪声样本的权重 | 不想损失数据量,且噪声分布相对已知 | 权重设置敏感,调参成本高 |
我个人的经验是:对于深度学习任务,优先尝试“纠正”而不是“删除”。因为深度模型需要大量数据,删掉5%可能比纠正那5%的影响更大。你可以先根据标签置信度排序,把最可疑的前几个挑出来人工看一下,如果确认是错误,再手动纠正或删除。
一个我花了很久才想通的问题:随机噪声 vs 系统性偏见
一开始我一度以为,去噪就是把那些“害群之马”揪出来。但后来发现,标注错误有两种:一种像白噪声,随机发生在任何类别上;另一种是系统性的,比如在医学影像里,医生总是把某个不常见病变漏掉,或者标注规范对边界明确的要求不统一。置信学习对随机噪声很有效,但对系统性偏见基本无能为力。因为它本质上是让模型自己找与自身预测不一致的样本;如果模型也被相同的偏见影响了,就找不出来了。这是当前数据去噪技术的一个真正的边界。
FAQ:三个最常见的问题
错误标签一定会让模型变差吗?
不一定。如果错误率很低,且错误是均匀随机的,模型可能把这些样本当成噪声忽视掉。但当错误率达到5%以上,或者错误集中在特定类别时,就会显著损害模型性能,尤其对线性模型和中小型深度学习模型。
交叉验证时用什么模型?
可以用你最终要用的模型,也可以用更简单的模型。关键是“样本外”。如果模型太弱,置信度不可靠;如果模型太强,又可能在噪声中记住坏样本。建议用与最终模型同结构但小一档的模型,或者多模型取平均。
去噪能完全消除噪声吗?
不能。置信学习给出的是“候选”错误,而不是“确定”错误。它只是帮你把人力检查的优先级排序。最终判断还是要靠人。
现在,我处理数据的第一步依然是:先跑一遍Cleanlab的默认流程,看看有多少样本被标为潜在错误。我很少直接删——我会把它当作一份“人工审核清单”。这个工具的价值不是替你决定哪些数据可以要,而是帮你把注意力集中到最可疑的那5%上。
它的边界也很清楚:假设数据错误是独立于特征的随机噪声,假设类别分布相对均衡,假设模型能在干净标签上训练到接近真实效果。一旦这些假设崩溃——比如错误标注本身就是特征的一部分,比如多个标注者对“模糊边界”的判定有系统分歧——机器能做的只是辅助,最终还是要人来下判断。去噪不是一次性的操作,它应该和你训练模型的流程绑定在一起。每当你多一次交叉验证,你就多了一次发现错误的机会。数据不会自己变干净,但你可以让模型帮你指出来。
原创文章,作者:guanweilu,如若转载,请注明出处:https://guanweilu.cn/article/1925.html