贝叶斯深度学习入门:从不确定性到贝叶斯神经网络
标准深度网络通常只吐出一个「点预测」:输入一张图,它告诉你这是猫的概率是 0.93。但它不会告诉你这个数字有多可信。在医疗诊断、自动驾驶、金融风控这类高风险场景里,知道模型「有多确定」往往和知道它「预测了什么」同样重要。一个把肺结节判为良性的模型,如果同时承认「我很不确定」,医生就该转人工复核;而一个自信满满却毫无依据的模型反而更危险。
本篇面向已经掌握深度学习基础、想理解模型不确定性的工程师,依次讲清四件事:为什么需要不确定性、贝叶斯视角如何把权重变成分布、贝叶斯神经网络(BNN)与两种主流近似方法(变分推断、MC Dropout),最后用 PyTorch 跑一个带不确定性估计的最小示例。
为什么需要不确定性:认知不确定性 vs 偶然不确定性
不确定性不是单一概念,至少可以分成两类,区分它们决定了你能「做什么」:
- 偶然不确定性(Aleatoric Uncertainty):来自数据本身的噪声与随机性,即使采到无穷多数据也无法消除。例如传感器测量误差、标注者之间的分歧。它又分「同质」(噪声大小恒定,即同方差)与「异质」(噪声随输入变化,即异方差,比如输入越模糊噪声越大)。
- 认知不确定性(Epistemic Uncertainty):来自模型自身知识不足,根因是训练数据覆盖不全、模型没见过的区域太多。它可以通过采集更多相关数据来减小。一句话概括:这是「模型不知道自己不知道」的那部分。
区分二者的意义很实际:偶然不确定性标出了任务本身的天花板,告诉你再怎么调模型也消除不了的误差;认知不确定性则告诉你「该去哪里补数据」。贝叶斯方法最擅长建模的正是认知不确定性,也能顺带扩展到建模偶然不确定性。
贝叶斯视角:权重是分布,不是点估计
普通训练(比如 SGD)得到的是一组权重的「点估计」w*,也就是损失函数在参数空间里的一个最优点。贝叶斯视角拒绝这种单一答案,它把权重 w 看成随机变量:
-
先验(Prior) p(w):在看到任何数据之前,你对权重长什么样的信念,通常是简单的分布(如零均值高斯)。
-
后验(Posterior) p(w|D):看到训练数据 D = {(x_i, y_i)} 之后,权重应该长什么样,由贝叶斯定理给出:
p(w|D) = p(D|w) · p(w) / p(D) ∝ p(D|w) · p(w)
-
预测(Predictive):对新输入 x*,预测分布不再依赖单一权重,而是对所有权重后验取期望(边缘化):
p(y* | x*, D) = ∫ p(y* | x*, w) · p(w|D) dw
直觉上,贝叶斯预测是「让无穷多个不同权重的模型各自投票,再按后验概率加权平均」,所以天然带有一个衡量分歧程度的方差。
难点在于:后验 p(w|D) 几乎从来没解析解,那个对权重的积分也不可解。于是「如何近似后验与预测分布」成了贝叶斯深度学习的全部重心。
贝叶斯神经网络(BNN):把贝叶斯装进神经网络
贝叶斯神经网络(Bayesian Neural Network,BNN)就是「每一层权重都是分布、而非定值」的神经网络。训练不再去求一个 w*,而是去求权重上的后验分布。直接算后验太难,于是有了两条主流近似路线。
变分推断:用一个好算的分布去逼近后验
变分推断的核心思路是:用一个带参数 θ 的、形式简单的分布 q_θ(w) 去逼近真实后验 p(w|D),衡量标准是两个分布的 KL 散度。训练目标是最大化「证据下界」(ELBO):
log p(D) ≥ E_{q_θ(w)}[ log p(D|w) ] − KL( q_θ(w) ‖ p(w) )
等号右边第一项鼓励 q 拟合数据(似然项),第二项约束 q 不要离先验太远。Bayes by Backprop(Blundell 等人,2015)用重参数化技巧直接对 ELBO 做反向传播,把每个权重替换成一个小分布来训练。
MC Dropout:用现成的 Dropout 近似贝叶斯
这是工程上最省力的近似,核心洞见来自 Gal 与 Ghahramani:如果在神经网络的每个权重层之后都放 Dropout,并把 Dropout 的训练解释成在「深度高斯过程」上做近似贝叶斯推断,那么推理时只要保持 Dropout 开启、多次前向采样,这批样本的均值和方差就能近似后验预测分布。
做法只需两步:
- 训练阶段和平时完全一样(标准 Dropout 训练)。
- 推理阶段调用
model.train()让 Dropout 在预测时仍然生效,对同一个输入前向跑 T 次,收集这 T 次输出,用均值当点估计、方差当不确定性。
它的优点是几乎零改动、额外计算开销小、能直接套在已有模型上;局限是对后验的近似偏乐观,方差校准不一定完美,复杂后验形状也表达不出来。
来源核验:Gal, Y. 与 Ghahramani, Z.《Dropout as a Bayesian Approximation: Representing Model Uncertainty in Deep Learning》,ICML 2016,arXiv:1506.02142。标题、作者、会议与核心主张(把 Dropout 训练视为深度高斯过程上的近似贝叶斯推断,并用 MC Dropout 估计模型不确定性)已通过 arXiv 摘要页核验(已核验)。
实战:用 PyTorch 做带不确定性估计的最小示例
下面用 MC Dropout 在一个一维回归任务上直观展示不确定性。我们先造一条带噪声的 y = sin(x) 曲线,训练一个带 Dropout 的小网络,然后推理时多次采样,对比「训练数据覆盖区」与「数据空白区」的方差差异。
import torch
import torch.nn as nn
import torch.optim as optim
# 生成带噪声的一维回归数据:y = sin(x) + 噪声
torch.manual_seed(0)
n_train = 80
x = torch.linspace(-3.0, 3.0, n_train).unsqueeze(1)
y = torch.sin(x) + 0.15 * torch.randn(n_train, 1)
# 定义带 Dropout 的 MLP;关键:推理阶段也保留 Dropout
class MCDropoutMLP(nn.Module):
def __init__(self):
super().__init__()
self.net = nn.Sequential(
nn.Linear(1, 64),
nn.ReLU(),
nn.Dropout(0.1),
nn.Linear(64, 64),
nn.ReLU(),
nn.Dropout(0.1),
nn.Linear(64, 1),
)
def forward(self, x):
return self.net(x)
model = MCDropoutMLP()
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=1e-3)
# 训练阶段:标准 MSE 优化,MC Dropout 不改动训练流程
for epoch in range(2000):
optimizer.zero_grad()
loss = criterion(model(x), y)
loss.backward()
optimizer.step()
# 推理阶段:保持 Dropout 开启,多次前向采样,用均值与方差刻画不确定性
def predict_with_uncertainty(model, x_test, n_samples=50):
model.train() # train() 模式让 Dropout 在推理时仍生效
predictions = [model(x_test) for _ in range(n_samples)]
preds = torch.stack(predictions, dim=0)
mean = preds.mean(dim=0)
var = preds.var(dim=0)
return mean, var
x_test = torch.linspace(-5.0, 5.0, 200).unsqueeze(1)
mean, var = predict_with_uncertainty(model, x_test)
# 区间外方差明显更大,正是认知不确定性的直观体现
print("测试点预测均值形状:", mean.shape)
print("训练区间内方差:", var[x_test.abs() < 3].mean().item())
print("训练区间外方差:", var[x_test.abs() >= 3].mean().item())
运行后你会看到:在训练数据覆盖的 [-3, 3] 区间内,多次采样的方差很小,说明模型「很有把握」;而在 [-5, -3) 和 (3, 5] 这类数据空白区,方差明显放大,说明模型「知道自己没见过」。这就是认知不确定性最直观的样子。把 mean 当预测值、var 的开方当置信区间半径,你就能画出让业务方放心的「带误差带的预测曲线」。
来源核验:PyTorch 官方站点(已核验)确认其为开源机器学习框架,提供
torch、torch.nn、autograd、optim等组件;本篇示例使用nn.Module与nn.Dropout构建网络。TensorFlow Probability 官方文档(已核验)确认其为「用于概率推理与统计分析的库」,构建于 TensorFlow,提供分布、bijectors、概率层、JointDistribution以及变分推断与 MCMC 工具,是做 BNN 的另一条成熟路线。
小结
回到开头的四个问题,一句话收束:
- 为什么需要不确定性:高风险决策里,「我有多确定」和「我预测了什么」同等重要,它区分了任务噪声的天花板与模型知识的缺口。
- 贝叶斯视角:权重不再是点,而是带先验、后验的分布;预测是对后验的边缘化,天然携带不确定性。
- BNN 与近似:真实后验算不出,于是用变分推断(学一个分布 q 逼近后验,最大化 ELBO)或用 MC Dropout(保持 Dropout 做多次采样)来近似。
- MC Dropout 最省力:训练照旧、推理多采样,均值即预测、方差即认知不确定性。
什么时候该用?主动学习(挑「最不确定」的样本去标注)、异常检测(高不确定性即异常)、少样本与分布外检测,以及任何「预测错了代价很高」的场景。
参考与延伸阅读
- Gal, Y. 与 Ghahramani, Z.《Dropout as a Bayesian Approximation: Representing Model Uncertainty in Deep Learning》,ICML 2016,arXiv:1506.02142(已核验)。
- TensorFlow Probability 官方文档(已核验):概率推理与统计分析库,构建于 TensorFlow,含分布、bijectors、概率层、JointDistribution、变分推断与 MCMC。
- PyTorch 官方文档(已核验):开源机器学习框架,
torch/torch.nn/autograd/optim组件,本篇示例使用其nn.Module与Dropout。 - Blundell, C. 等人,2015,《Weight Uncertainty in Neural Networks》(Bayes by Backprop)(待核实,本文未做 WebFetch 核验,建议引用前自行核对)。
- Kendall, A. 与 Gal, Y.,2017,《What Uncertainties Do We Need in Bayesian Deep Learning for Computer Vision》(偶然与认知不确定性分解)(待核实,本文未做 WebFetch 核验,建议引用前自行核对)。