模型90%置信还翻车?一篇讲透证据深度学习,手把手教会模型说“我不知道“
2026/8/19 19:16:33 网站建设 项目流程

模型90%置信还翻车?一篇讲透证据深度学习,手把手教会模型说"我不知道"

【免费下载链接】annotated_deep_learning_paper_implementations🧑‍🏫 60+ Implementations/tutorials of deep learning papers with side-by-side notes 📝; including transformers (original, xl, switch, feedback, vit, ...), optimizers (adam, adabelief, sophia, ...), gans(cyclegan, stylegan2, ...), 🎮 reinforcement learning (ppo, dqn), capsnet, distillation, ... 🧠项目地址: https://gitcode.com/gh_mirrors/an/annotated_deep_learning_paper_implementations

如果你花了两周训出一个在测试集上准确率 99% 的分类模型,部署第一天就被一张模糊图片"打脸"——它信誓旦旦给出 95% 置信度,结果完全判错——那你大概率正被一个老毛病困扰:模型过度自信。要根治它,annotated_deep_learning_paper_implementations 项目里的证据深度学习(Evidential Deep Learning)模块值得你花半小时读懂:它位于 labml_nn/uncertainty/evidence/,专门用来量化分类模型的不确定性,让 AI 学会在拿不准的时候老实说"我不知道"。

一个真实翻车现场:99% 置信度的分类器,为何在真实场景不堪一击

假设你是一家工厂的质检工程师,负责用视觉模型筛选皮带轮瑕疵。训练集里全是清晰锐利的样本,模型表现近乎完美。可某天来了一张带水渍、光线诡异的图片,模型非但不犹豫,反而以 96% 的"把握"判为良品,随后流入市场。更气人的是,你回头查看推理日志,发现它给出的概率分布"非常干净"——某个类别几乎独占 1.0。这合理吗?显然不合理,但如果你只用了 softmax,你甚至找不到地方说理。

softmax 概率到底在说什么?——"矮子里拔将军"式的归一化

先给个"人话版"解释:softmax 的作用只是把一堆任意数值归一化成总和为 1。它保证的是"这些类里谁相对更高",而不是"这个判断有多可靠"。它像一场不允许弃权的考试——哪怕完全不会,也必须每题都写个答案,最后每道题都得有分数。哪怕输入来自它完全没见过的分布,它照样能吐出一个看起来胸有成竹的漂亮分布。

两种"不知道",别混为一谈

  • 偶然不确定性(aleatoric):数据本身模糊——图片虚焦、类别天然重叠。这种不确定性给再多数据也消不掉,物理世界里它就长这样。
  • 认知不确定性(epistemic):模型"见识不够"——训练分布外的东西、没见过的新情况。这种不确定性可以通过更多数据、更充分的训练来降低。

对部署来说,真正要命的是第二种:模型把"没见过"误当成"很确定"。而证据深度学习最擅长的,正是把这种"没见过"显式地量化出来。

破局思路:别逼模型表态,给它一张"弃权票"

证据深度学习的理论根基是 Dempster–Shafer 证据理论。它和 softmax 最大的不同在于:不再把概率一次性押在"某一个类"上,而是把"信念质量"分配给一组类。当模型说"我对所有类都持有信念"时,意思就是——"这个我真拿不准,可能是任何一个"。

这就像一位老练的医生看 CT 片子:看得准的时候明确说"倾向于是 A 病";看不准的时候,不会硬编结论,而是说"这个影像我不能确定,建议做进一步检查"。证据深度学习给了模型说"建议进一步检查"的合法出口——这个出口就是不确定性质量 u

信念质量与不确定性质量:一张票怎么分

模型对每个类输出一个非负的"证据" e_k,表示"我收集到多少支持第 k 类的线索",然后换算成两个量:

  • 信念质量 b_k = e_k / S
  • 不确定性质量 u = K / S

其中 S = Σ(e_k + 1),K 是类别数,并且 u + Σb_k = 1 恒成立。直觉上非常好懂:如果所有证据都小得可怜,S 就接近 K,u 逼近 1——模型等于在说"我什么都没见过,全靠猜";如果某一类的证据异常庞大,S 被顶上去,u 趋近于 0——模型非常笃定。证据越多,弃权票越少,逻辑完全自洽。

为什么 u 比 softmax 概率诚实

softmax 的结构决定了它永远"被迫表态";而 u 是专门用来装"我不知道"的桶。一个对分布外输入给出高 u 的模型,比一个强行归一化给出 95% 的模型,在工程上可信得多——因为前者没有把无知伪装成自信。这也是证据深度学习作为深度学习不确定性估计方案,与朴素"加个置信度"最大的分野。

证据从哪来?——最后一层换成 ReLU/Softplus 就够了

好消息是:你不必重写模型。证据深度学习只动"最后一层之后"。原本输出 logits(可以是负数)的最后一层,在外面套一个 ReLU 或 Softplus 激活函数,就把输出限制成非负的证据 e_k ≥ 0;证据再通过一步换算变成狄利克雷分布的参数 α_k = e_k + 1。

狄利克雷分布可以理解成"对类别概率分布的概率分布"。它像抛硬币实验里的贝叶斯更新:你只抛了 10 次,得到的概率估计很平坦、很没底;抛了一万次,估计就尖锐、笃定。证据多,α 大,分布尖锐;证据少,α 接近 1,分布平坦。整套换算在源码 labml_nn/uncertainty/evidence/init.py 里不过几十行。

证据→狄利克雷:核心换算只有三个数

给定证据向量 e,你只需要记住三个派生量:

  • 狄利克雷参数 α_k = e_k + 1
  • 狄利克雷强度 S = Σα_k
  • 期望概率 p̂_k = α_k / S,不确定性 u = K / S

p̂_k 负责"该选哪一类"(决策),u 负责"这次决策可不可信"(信任度)。一个管冲锋,一个管刹车,各司其职。

训练"诚实模型"的四份考卷:选错损失会教坏孩子

光有结构还不够,模型得靠损失函数学会"何时该有把握、何时该认怂"。项目实现了三种可选的"主损失",外加一份常驻的"正则附加题",完整清单都在 labml_nn/uncertainty/evidence/init.py 里。

考卷一、二:最大似然与交叉熵贝叶斯风险

  • MaximumLikelihoodLoss(类型二最大似然):把狄利克雷当成先验,对类别概率积分后求负对数边际似然,鼓励正确类别积累证据。
  • CrossEntropyBayesRisk(交叉熵贝叶斯风险):把交叉熵当作"判断错误的代价",在所有可能的类别概率分布上求期望代价,公式里会出现 digamma 函数。简单说:它既看答案对不对,也看代价大不大。

考卷三:平方误差风险——把"误差"和"方差"拆开算

这是训练实验里的默认选项,也最值得玩味。它的损失可以优雅地拆成两项:

(y_k − p̂_k)² + p̂_k(1 − p̂_k) / (S + 1)

第一项是"答案偏了多少"(误差项),第二项是"这个估计本身有多没底"(方差项),而且方差会随着狄利克雷强度 S 增大而缩小。换句话说,模型想降低损失,光答对不行,还得把证据做足、让底气和准确度一起提上来——这恰好是"诚实"的数学化表达。

考卷四:KL 正则——答错时不许硬撑

KLDivergenceLoss 是始终叠加的正则项:先把"正确类"的证据从样本里摘掉(α̃ = y + (1−y)α),再让剩下的分布尽量贴近"完全无知"的均匀先验。翻译成人话就是:如果一个样本你没把握答对,那就老老实实把证据收到接近零,别为了凑答案硬编证据。

照着源码跑一遍 MNIST:三个值得抄走的工程细节

项目提供了开箱即用的 MNIST 训练脚本 labml_nn/uncertainty/evidence/experiment.py,用的是 LeNet 风格的小网络,配合 Adam、0.5 的 Dropout,默认用 Softplus 出证据、平方误差贝叶斯风险做主损失。直接照抄时,有三个细节特别值得留意。

细节一:KL 惩罚要"退火",先学会再要求诚实

训练早期就施加强 KL 正则,会让模型"躺平"——反正答错也不罚,干脆什么都不学。项目用一个退火系数 λ_t 从 0 平滑升到 1(对应训练进度 0%→20%→100% 分别是 0→0.01→1),让模型先正常学会分类,再逐步加强"不许硬撑"的要求。这个"先学走路、再立规矩"的思路,是能直接搬到其他任务上的通用技巧。

细节二:训练时就盯住 u.succ 与 u.fail 两条曲线

TrackStatistics 模块会在训练中分别统计"预测正确时的不确定性"和"预测错误时的不确定性"。理想情况下,答错的样本 u 应该明显高于答对的样本——如果两条曲线几乎重合,说明模型还没学会区分"懂"和"不懂",该调损失函数或证据激活了。把它当成模型的"诚实度仪表盘"来用。

细节三:证据转换选 Softplus 比 ReLU 更稳

ReLU 会把负数直接截成 0,导致大量样本的证据为零、梯度容易消失;Softplus 光滑且处处可微,输出永远是正数,训练更稳。除非你有明确理由,否则别轻易换回 ReLU。

让"不确定性"真正上岗:三个落地动作

模型学会了说"不知道",接下来就看你怎么用这个信号。

动作一:给 u 设阈值,把低置信样本转人工

在生产里给 u 定一个阈值(用验证集标定),u 超限的样本不直接给结论,而是进入人工复核队列。这相当于给系统装了一条"拿不准就问人"的逃生通道,对质检、医疗、风控这类场景几乎是刚需。

动作二:用高 u 样本做主动学习

把不确定性当成"哪些数据最值得标注"的信号:优先让人工标注 u 高的样本,往往能用最少的人力最快提升模型在疑难区域的性能,比随机采样划算得多。

动作三:风险敏感场景把 u 写进决策函数

当"错判"和"拒答"的代价不对称时(比如把次品放行 vs 把良品拦下复检),可以把 u 直接作为决策权重,让系统在拿不准时自动倾向更安全的动作,而不是硬着头皮二选一。

写在最后:给 AI 装刹车,而不是只教它踩油门

回头看那个翻车现场,问题的根源不在于模型不够聪明,而在于我们训练它时,从来没给它"承认无知"的选项。证据深度学习最打动人的地方,是它把"我不知道"变成了一等公民:结构上给你弃权票(不确定性 u),训练上给你诚实的考卷(四类损失),部署上给你可操作的信号(u 阈值、主动学习)。

如果你想亲手感受这种变化,最快的方式是克隆仓库 https://gitcode.com/gh_mirrors/an/annotated_deep_learning_paper_implementations ,跑一遍 labml_nn/uncertainty/evidence/experiment.py 的 MNIST 实验,再对比三种主损失下的 u.succ 与 u.fail 曲线。当你在训练日志里亲眼看到"答错的样本不确定性明显更高"那一刻,你会理解:一个真正可靠的 AI,重要的不是永远答对,而是永远知道自己几斤几两。配套的图文解读还可以在 docs/uncertainty/evidence/ 里找到。

【免费下载链接】annotated_deep_learning_paper_implementations🧑‍🏫 60+ Implementations/tutorials of deep learning papers with side-by-side notes 📝; including transformers (original, xl, switch, feedback, vit, ...), optimizers (adam, adabelief, sophia, ...), gans(cyclegan, stylegan2, ...), 🎮 reinforcement learning (ppo, dqn), capsnet, distillation, ... 🧠项目地址: https://gitcode.com/gh_mirrors/an/annotated_deep_learning_paper_implementations

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询