神经网络作为概率图模型
概述
**概率图模型(Probabilistic Graphical Models, PGMs)和神经网络(Neural Networks, NNs)**是现代机器学习的两大支柱。传统观点将它们视为截然不同的范式:PGM强调显式的概率建模和结构化推理,而NN则强调端到端的表示学习。然而,从更深层次来看,这两者之间存在着深刻的内在联系。1
本文从概率图模型的视角重新审视神经网络,建立统一的理论框架,揭示:
┌─────────────────────────────────────────────────────────────────────┐
│ 神经网络 ↔ 概率图模型 统一视角 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ 神经网络 │ ───▶ │ 有向无环图 │ │
│ │ (确定性计算) │ │ (贝叶斯网络) │ │
│ └─────────────────┘ └─────────────────┘ │
│ ↕ ↕ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ 权重参数 │ ───▶ │ 随机变量 │ │
│ │ w ∈ ℝ^d │ │ W ∈ p(W) │ │
│ └─────────────────┘ └─────────────────┘ │
│ ↕ ↕ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ 激活函数 │ ───▶ │ 势函数 │ │
│ │ σ(·) │ │ ψ(·) │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 统一框架:变分推断 + 深度学习 │ │
│ │ VAE、BNN、扩散模型 ← 深度概率模型 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
1. 神经网络与概率图模型的对应关系
1.1 网络结构与图结构
从结构角度看,神经网络本身就是一种图结构。每一层神经元构成图的节点层,连接权重构成边。这种结构与概率图模型中的图结构存在直接的对应关系。
1.1.1 前馈神经网络的图表示
考虑一个 层的前馈神经网络,其计算过程可表示为:
其中 为输入, 为输出。
从概率图模型视角,这可以理解为一个有序因子分解:
其中每个势函数对应一层网络:
是 Dirac delta 函数,表示确定性变换。
1.1.2 结构对应表
| 神经网络组件 | 概率图模型组件 | 数学表示 |
|---|---|---|
| 输入层 | 观测变量 | |
| 隐藏层 | 隐变量 | |
| 权重 | 条件概率表 | |
| 激活函数 | 势函数 | |
| 输出层 | 推断变量 |
1.2 权重与随机变量
传统神经网络将权重视为确定性的点估计。然而,从概率图模型的角度,我们可以将权重建模为随机变量,这构成了贝叶斯神经网络的基础。
1.2.1 从点估计到分布
标准神经网络(点估计):
贝叶斯神经网络(分布估计):
其中 是权重的后验分布。
1.2.2 权重先验的选择
权重的先验分布 对模型行为有重要影响:
各向同性高斯先验:
自动相关性确定(ARD)先验:
其中 是超参数,允许模型自动选择相关特征。
层次化先验:
这允许从数据中学习先验结构。
1.3 激活函数与势函数
激活函数在概率图模型中对应势函数(Potential Functions)。势函数定义了变量之间的局部兼容性或能量关系。
1.3.1 势函数的观点
在马尔可夫随机场中,势函数 定义在团(clique)上,定义了局部配置的”能量”或”兼容性”。
神经网络的激活函数可以视为一种参数化势函数:
1.3.2 常见激活函数的势函数解释
Sigmoid 激活:
从势函数角度看,sigmoid 定义了一个软阈值势,将线性组合转换为概率形式的响应。
ReLU 激活:
ReLU 可视为分段线性势函数,对应稀疏的激活模式。
Softplus 激活:
这是 ReLU 的平滑版本,可视为高斯势函数的负对数。
1.3.3 注意力机制的势函数解释
在 Transformer 架构中,注意力机制可以自然地解释为软化的消息传递:
从概率图模型角度看:
- Query :当前节点的”查询”
- Key :邻居节点的”键”
- Value :邻居节点的”值”
- Softmax:归一化势函数,产生消息权重
这等价于因子图中的归一化消息传递。
2. 变分推断统一框架
2.1 ELBO与证据下界
变分推断是连接神经网络与概率图模型的核心桥梁。给定观测数据 ,我们希望推断隐变量 的后验分布 。
2.1.1 ELBO 的推导
设 为近似后验分布,变分推断优化以下目标:
展开联合分布 :
**证据下界(ELBO)**的性质:
- 下界性:
- 紧度:
- 可优化性:最大化 ELBO 等价于最小化近似后验与真实后验的 KL 散度
2.1.2 ELBO 的图形解释
┌─────────────────────────────────────────────────────────────────────┐
│ ELBO 的分解 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ log p(x) │
│ │ │
│ │ ┌──────────────────────────────────┐ │
│ │ │ │ │
│ │ │ 重建项 │ │
│ │ │ E_q[log p(x|z)] │ │
│ │ │ │ │
│ └──►│──────────────────────────────────│ │
│ │ │ │ │
│ │ │ 正则化项 │ │
│ │ │ - D_KL(q(z)||p(z)) │ │
│ └──►│──────────────────────────────────│◀── ELBO │
│ │ │ │ │
│ │ └──────────────────────────────────┘ │
│ │ │
│ │ 剩余差距 = D_KL(q(z)||p(z|x)) │
│ │ │
│ log p(x) │
│ │
└─────────────────────────────────────────────────────────────────────┘
2.2 神经网络中的变分推断
2.2.1 变分自编码器(VAE)
变分自编码器(Variational Autoencoder, VAE)是变分推断与神经网络结合的经典案例。
概率模型:
- 先验:
- 似然:
- 编码器:
ELBO 目标:
其中 是权衡参数。
重参数化技巧:
为使梯度能够流经随机节点,我们使用重参数化:
这使得 的采样操作可微。
2.2.2 VAE 的 PyTorch 实现
import torch
import torch.nn as nn
import torch.nn.functional as F
class VAE(nn.Module):
"""
变分自编码器实现
概率图模型视角:
- 编码器 q(z|x): 近似后验分布
- 解码器 p(x|z): 生成模型
- 先验 p(z): 标准高斯分布
"""
def __init__(self, input_dim: int, latent_dim: int, hidden_dim: int = 400):
super().__init__()
self.latent_dim = latent_dim
# 编码器:近似后验 q(z|x)
self.encoder = nn.Sequential(
nn.Linear(input_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, hidden_dim),
nn.ReLU()
)
self.fc_mu = nn.Linear(hidden_dim, latent_dim)
self.fc_logvar = nn.Linear(hidden_dim, latent_dim)
# 解码器:似然 p(x|z)
self.decoder = nn.Sequential(
nn.Linear(latent_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, input_dim),
nn.Sigmoid()
)
def encode(self, x: torch.Tensor):
"""编码:计算近似后验参数"""
h = self.encoder(x)
mu = self.fc_mu(h)
logvar = self.fc_logvar(h)
return mu, logvar
def reparameterize(self, mu: torch.Tensor, logvar: torch.Tensor):
"""重参数化技巧:z = μ + σ·ε"""
std = torch.exp(0.5 * logvar)
eps = torch.randn_like(std)
return mu + std * eps
def decode(self, z: torch.Tensor):
"""解码:计算似然参数"""
return self.decoder(z)
def forward(self, x: torch.Tensor):
"""前向传播"""
mu, logvar = self.encode(x)
z = self.reparameterize(mu, logvar)
x_recon = self.decode(z)
return x_recon, mu, logvar
def elbo_loss(self, x: torch.Tensor, beta: float = 1.0):
"""计算 ELBO 损失"""
mu, logvar = self.encode(x)
z = self.reparameterize(mu, logvar)
x_recon = self.decode(z)
# 重建项:-E_q[log p(x|z)]
recon_loss = F.binary_cross_entropy(x_recon, x, reduction='sum')
# KL 正则化项:D_KL(q(z|x) || p(z))
# D_KL = -0.5 * sum(1 + log(σ²) - μ² - σ²)
kl_loss = -0.5 * torch.sum(
1 + logvar - mu.pow(2) - logvar.exp()
)
return recon_loss + beta * kl_loss, recon_loss, kl_loss2.3 随机变分推断(SVI)
当数据集规模很大时,精确的变分推断变得不可行。**随机变分推断(Stochastic Variational Inference, SVI)**通过小批量随机采样来解决这个问题。2
2.3.1 SVI 的核心思想
对于数据集 ,ELBO 可分解为:
使用小批量 近似:
2.3.2 SVI 的收敛性
定理(SVI 收敛性):
设学习率 满足 和 ,则在温和条件下,随机梯度上升收敛到局部最优。
自适应学习率:
- 使用 Adam 或 RMSprop 等自适应优化器
- 自然梯度 ,其中 是 Fisher 信息矩阵
2.4 变分推断与神经网络训练的统一
变分推断提供了一种统一视角来看待各种神经网络训练目标:
| 方法 | 目标函数 | 与 ELBO 的联系 |
|---|---|---|
| 标准 MLE | 的 ELBO | |
| MAP 估计 | 确定性后验 | |
| VAE | ||
| -VAE | 可控解纠缠 | |
| InfoGAN | 加入互信息约束 |
3. 神经网络作为无限树结构PGM
3.1 宽度极限分析
考虑一个无限宽的神经网络,其隐藏层宽度 。在这种极限下,神经网络的行为可以用高斯过程(Gaussian Process)来描述。
3.1.1 神经网络作为高斯过程
设神经网络的权重初始化为 ,偏置初始化为 。
定理(NNGP 定理):
对于无限宽的神经网络(无 skip connection),在权重独立同分布初始化下,隐藏节点的输出分布趋向于均值 、协方差为某个核函数 的高斯过程。
递归核计算:
其中 和 是第 层输出的隐向量。
对于 ReLU 激活函数:
3.1.2 有限宽度修正:NTK
**神经正切核(Neural Tangent Kernel, NTK)**描述了神经网络在训练过程中的动态特性。3
在无限宽度极限下,NTK 保持常数:
这意味着在无限宽度下,神经网络的训练动态可以解析求解。
3.2 深度极限分析
考虑深度固定、宽度趋向无穷的情况。深度增加时,神经网络的表现力发生变化。
3.2.1 深度高斯过程
深度神经网络可以视为深度高斯过程的均值函数近似:
定理(深度极限):
当宽度 时,对于足够”好”的激活函数(如 ReLU、erf),深度神经网络的输出趋向于某个广义高斯过程。
3.2.2 深度与表达力的关系
| 深度 | 宽度 | 表达力 | 极限行为 |
|---|---|---|---|
| 线性函数空间 | 高斯过程 | ||
| 非线性函数空间 | 高斯过程 + 非线性核 | ||
| 有限 | 任意连续函数 | Neural ODE | |
| 随机函数空间 | 随机过程 |
3.3 变分近似与无限宽度极限
3.3.1 贝叶斯神经网络的后验近似
精确计算贝叶斯神经网络的后验 是 intractable 的,因为权重数量通常达到百万甚至十亿级别。
变分近似的选择:
-
均值场近似:
-
随机矩阵近似:
假设权重矩阵满足某种随机结构,简化协方差计算 -
NTK 近似:
在无限宽度极限下,使用确定的 NTK 代替权重后验
3.3.2 变分推断的蒙特卡洛估计
对于大规模神经网络,变分推断的 ELBO 损失需要用蒙特卡洛采样估计:
class StochasticVI(nn.Module):
"""
随机变分推断实现
核心思想:
1. 使用小批量数据近似全数据 ELBO
2. 使用重参数化采样估计期望
3. 使用随机优化器更新变分参数
"""
def __init__(self, model, prior_std=1.0):
super().__init__()
self.model = model
self.prior_std = prior_std
# 变分参数:每个权重维护 (μ, log σ²)
self.variational_params = nn.ParameterDict()
for name, param in model.named_parameters():
self.variational_params[f'{name}_mu'] = nn.Parameter(param.data.clone())
self.variational_params[f'{name}_logvar'] = nn.Parameter(
torch.zeros_like(param.data)
)
def sample_weights(self):
"""从变分分布采样权重"""
sampled_params = {}
for name, param in self.model.named_parameters():
mu = self.variational_params[f'{name}_mu']
logvar = self.variational_params[f'{name}_logvar']
std = torch.exp(0.5 * logvar)
# 重参数化采样
eps = torch.randn_like(std)
sampled_params[name] = mu + std * eps
return sampled_params
def elbo(self, x, y, n_mc_samples=1):
"""
计算 ELBO 的蒙特卡洛估计
ELBO = E_q[log p(y|x,θ)] - D_KL(q(θ)||p(θ))
"""
# 重构损失的蒙特卡洛估计
log_likelihoods = []
for _ in range(n_mc_samples):
weights = self.sample_weights()
# 加载采样权重
with torch.no_grad():
for name, param in self.model.named_parameters():
param.copy_(weights[name])
# 计算对数似然
logits = self.model(x)
log_likelihood = torch.nn.functional.cross_entropy(
logits, y, reduction='mean'
)
log_likelihoods.append(log_likelihood)
recon_loss = -torch.stack(log_likelihoods).mean()
# KL 散度
kl_loss = 0.0
for name, param in self.model.named_parameters():
mu = self.variational_params[f'{name}_mu']
logvar = self.variational_params[f'{name}_logvar']
# D_KL(N(μ,σ²) || N(0,σ_p²))
kl = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp() / self.prior_std**2)
kl_loss += kl
return recon_loss + kl_loss / x.size(0), recon_loss, kl_loss4. 深度概率模型
4.1 变分自编码器(VAE)深入分析
4.1.1 VAE 的概率图模型解释
VAE 定义了一个完整的概率图模型:
有向图结构:
x ──▶ z ──▶ x'
│ │
q(z|x) p(x|z)
│ │
└──┬─┘
↓
边缘化:p(x) = ∫ p(x|z)p(z)dz
生成过程:
- 从先验采样潜在代码:
- 从似然生成观测:
推断过程:
- 给定观测 ,推断后验:
4.1.2 -VAE 与解纠缠
标准 VAE 可能在潜在空间中出现纠缠。-VAE 通过调整 KL 项的权重来促进解纠缠(disentanglement)。4
解纠缠度量:
使用变分推断高级技巧中的解纠缠度量,如 Mean Correlation (MIG) 或 DCI:
其中 是第 个潜在维度与第 个生成因子的互信息。
4.2 变分推断与神经网络训练
4.2.1 对比:标准训练 vs 变分训练
标准训练(MLE/MAP):
问题:过拟合、缺乏不确定性估计、无法处理小样本
变分训练(VI):
优点:正则化、隐式集成、概率输出
4.2.2 优化器选择
变分推断的优化面临特殊挑战:
| 优化器 | 适用场景 | 特点 |
|---|---|---|
| Adam | 大多数场景 | 自适应学习率,收敛稳定 |
| Natural Adam | 高维参数空间 | 使用 Fisher 信息矩阵校正 |
| Riemannian Adam | 流形优化 | 在黎曼流形上优化 |
class NaturalGradientOptimizer:
"""
自然梯度优化器
在变分推断中,自然梯度考虑了参数空间的几何结构,
提供更有效的更新方向。
自然梯度:∇̃q = F⁻¹ · ∇θ
其中 F 是 Fisher 信息矩阵
"""
def __init__(self, params, lr=0.001, damping=1e-3):
self.params = list(params)
self.lr = lr
self.damping = damping
self.m = [] # 一阶矩估计
self.v = [] # 二阶矩估计
self.t = 0
# 初始化
for p in self.params:
self.m.append(torch.zeros_like(p))
self.v.append(torch.zeros_like(p))
def step(self, grads):
"""
自然梯度更新步骤
近似 Fisher 信息矩阵的逆:
F ≈ diag(v + ε)
"""
self.t += 1
beta1, beta2 = 0.9, 0.999
updated_params = []
for i, (p, g) in enumerate(zip(self.params, grads)):
# 偏差校正
m_hat = self.m[i] / (1 - beta1 ** self.t)
v_hat = self.v[i] / (1 - beta2 ** self.t)
# 自然梯度更新
# 使用 v_hat 的逆作为 Fisher 近似的逆
nat_grad = m_hat / (torch.sqrt(v_hat) + self.damping)
# 更新参数
p_new = p - self.lr * nat_grad
# 更新动量估计
self.m[i] = beta1 * self.m[i] + (1 - beta1) * g
self.v[i] = beta2 * self.v[i] + (1 - beta2) * g * g
updated_params.append(p_new)
return updated_params4.3 贝叶斯神经网络
4.3.1 BNN 的概率图模型表示
贝叶斯神经网络将变分推断应用于神经网络权重:
其中
BNN 的 ELBO:
4.3.2 MC Dropout 作为变分推断
MC Dropout提供了一种实用的变分推断近似,无需修改网络架构。
理论联系:
Dropout 在训练时等效于对网络添加 Bernoulli 噪声,在测试时通过多次采样可近似贝叶斯推断。
class MCDropout(nn.Module):
"""
MC Dropout 实现
原理:
- Dropout 在训练时等价于对权重应用变分分布
- MC Dropout 在测试时多次采样,估计预测不确定性
"""
def __init__(self, model, n_samples=30):
super().__init__()
self.model = model
self.n_samples = n_samples
# 确保 dropout 在 eval 模式下仍然生效
for m in self.model.modules():
if isinstance(m, nn.Dropout):
m.train()
def predict(self, x):
"""
多次采样预测
返回:
- mean: 预测均值
- std: 预测标准差(不确定性)
"""
predictions = []
with torch.no_grad():
for _ in range(self.n_samples):
y_pred = self.model(x)
predictions.append(y_pred)
predictions = torch.stack(predictions)
# 统计
mean = predictions.mean(dim=0)
std = predictions.std(dim=0)
return mean, std
def predict_class(self, x):
"""分类预测:返回类别和置信度"""
mean, std = self.predict(x)
probs = torch.softmax(mean, dim=-1)
# 置信度 = 预测概率 * (1 - 预测熵)
confidence = probs * (1 - (-probs * torch.log(probs + 1e-8)).sum(dim=-1, keepdim=True))
return mean.argmax(dim=-1), confidence5. 应用案例
5.1 图像生成
5.1.1 VAE 用于图像生成
变分自编码器是扩散模型出现前的主要生成模型之一。
应用特点:
- 快速推理:无需迭代采样
- 连续潜在空间:支持插值和编辑
- 概率输出:自然的不确定性估计
class ImageVAE(nn.Module):
"""
图像生成 VAE
架构:
- 编码器:层次化压缩图像信息
- 潜在空间:hierarchical VAE (HVAE)
- 解码器:从潜在空间重建图像
"""
def __init__(self, in_channels=3, latent_dim=128, hidden_dim=256):
super().__init__()
# 编码器
self.encoder = nn.Sequential(
# 128x128 -> 64x64
nn.Conv2d(in_channels, hidden_dim//4, 4, 2, 1),
nn.BatchNorm2d(hidden_dim//4),
nn.ReLU(),
# 64x64 -> 32x32
nn.Conv2d(hidden_dim//4, hidden_dim//2, 4, 2, 1),
nn.BatchNorm2d(hidden_dim//2),
nn.ReLU(),
# 32x32 -> 16x16
nn.Conv2d(hidden_dim//2, hidden_dim, 4, 2, 1),
nn.BatchNorm2d(hidden_dim),
nn.ReLU(),
# 16x16 -> 8x8
nn.Conv2d(hidden_dim, hidden_dim, 4, 2, 1),
nn.BatchNorm2d(hidden_dim),
nn.ReLU(),
)
# 潜在参数
self.fc_mu = nn.Linear(hidden_dim * 8 * 8, latent_dim)
self.fc_logvar = nn.Linear(hidden_dim * 8 * 8, latent_dim)
# 解码器
self.fc_decode = nn.Linear(latent_dim, hidden_dim * 8 * 8)
self.decoder = nn.Sequential(
# 8x8 -> 16x16
nn.ConvTranspose2d(hidden_dim, hidden_dim, 4, 2, 1),
nn.BatchNorm2d(hidden_dim),
nn.ReLU(),
# 16x16 -> 32x32
nn.ConvTranspose2d(hidden_dim, hidden_dim//2, 4, 2, 1),
nn.BatchNorm2d(hidden_dim//2),
nn.ReLU(),
# 32x32 -> 64x64
nn.ConvTranspose2d(hidden_dim//2, hidden_dim//4, 4, 2, 1),
nn.BatchNorm2d(hidden_dim//4),
nn.ReLU(),
# 64x64 -> 128x128
nn.ConvTranspose2d(hidden_dim//4, in_channels, 4, 2, 1),
nn.Tanh() # 输出 [-1, 1]
)
def encode(self, x):
h = self.encoder(x).view(x.size(0), -1)
return self.fc_mu(h), self.fc_logvar(h)
def decode(self, z):
h = self.fc_decode(z).view(z.size(0), -1, 8, 8)
return self.decoder(h)
def forward(self, x):
mu, logvar = self.encode(x)
z = self.reparameterize(mu, logvar)
x_recon = self.decode(z)
return x_recon, mu, logvar
def reparameterize(self, mu, logvar):
std = torch.exp(0.5 * logvar)
eps = torch.randn_like(std)
return mu + std * eps5.2 异常检测
5.2.1 基于重构概率的异常检测
深度概率模型可用于异常检测,异常样本通常具有较低的重构概率。
方法:
- 在正常数据上训练 VAE
- 定义异常分数:
- 异常样本的重构概率较低
class AnomalyDetector:
"""
基于 VAE 的异常检测器
异常分数定义:
- 重构误差:AEL = ||x - x_recon||²
- 负对数似然:NLL = -E_q[log p(x|z)]
- 组合分数:score = AEL + λ · (-log p(z))
"""
def __init__(self, vae, threshold=0.0):
self.vae = vae
self.threshold = threshold
self.device = next(vae.parameters()).device
def compute_anomaly_score(self, x, n_samples=10):
"""计算异常分数"""
x = x.to(self.device)
scores = []
with torch.no_grad():
for _ in range(n_samples):
# 多次采样以获得稳定估计
x_recon, mu, logvar = self.vae(x)
# 重构误差
recon_error = torch.sum((x - x_recon) ** 2, dim=[1, 2, 3])
# KL 散度(潜在代码的负对数先验)
kl_div = -0.5 * torch.sum(
1 + logvar - mu.pow(2) - logvar.exp(),
dim=1
)
score = recon_error + 0.1 * kl_div
scores.append(score)
return torch.stack(scores).mean(dim=0)
def detect(self, x, return_scores=False):
"""
异常检测
返回:
- is_anomaly: 布尔张量
- scores: 异常分数(可选)
"""
scores = self.compute_anomaly_score(x)
is_anomaly = scores > self.threshold
if return_scores:
return is_anomaly, scores
return is_anomaly
def fit(self, data_loader, device='cuda'):
"""在正常数据上训练 VAE"""
self.device = device
self.vae = self.vae.to(device)
optimizer = torch.optim.Adam(self.vae.parameters(), lr=1e-4)
for epoch in range(50):
epoch_loss = 0
for x, in data_loader:
x = x.to(device)
loss, _, _ = self.vae.elbo_loss(x)
optimizer.zero_grad()
loss.backward()
optimizer.step()
epoch_loss += loss.item()
print(f"Epoch {epoch}: Loss = {epoch_loss / len(data_loader):.4f}")
return self5.3 不确定性量化
5.3.1 认知不确定性 vs 偶然不确定性
在贝叶斯神经网络的不确定性量化中,有两种主要不确定性:
偶然不确定性(Aleatoric):
- 来自数据本身的随机性
- 无法通过更多数据减少
- 通过异方差似然建模
认知不确定性(Epistemic):
- 来自模型参数的不确定性
- 可以通过更多数据减少
- 通过权重后验建模
class UncertaintyQuantifier:
"""
不确定性量化器
结合:
1. 认知不确定性:BNN 权重后验
2. 偶然不确定性:异方差输出层
"""
def __init__(self, model, n_mc_samples=30):
self.model = model
self.n_mc_samples = n_mc_samples
def predict_uncertainty(self, x):
"""
预测带不确定性的输出
返回:
- mean: 预测均值
- epistemic_std: 认知不确定性(模型不确定性)
- aleatoric_std: 偶然不确定性(数据噪声)
- total_std: 总不确定性
"""
mean_list = []
var_list = []
self.model.train() # 启用 dropout
for _ in range(self.n_mc_samples):
out = self.model(x)
# 假设输出是 (mean, log_var) 或单独的均值
if isinstance(out, tuple):
mean, log_var = out
aleatoric_var = torch.exp(log_var)
else:
mean = out
aleatoric_var = torch.zeros_like(mean)
mean_list.append(mean)
var_list.append(aleatoric_var)
self.model.eval()
# 计算统计量
mean_stack = torch.stack(mean_list)
var_stack = torch.stack(var_list)
# 预测均值 = E[μ]
mean = mean_stack.mean(dim=0)
# 认知不确定性 = Var[μ]
epistemic_var = mean_stack.var(dim=0)
# 偶然不确定性 = E[σ²]
aleatoric_var = var_stack.mean(dim=0)
# 总不确定性 = Var[μ] + E[σ²]
total_var = epistemic_var + aleatoric_var
return {
'mean': mean,
'epistemic_std': torch.sqrt(epistemic_var),
'aleatoric_std': torch.sqrt(aleatoric_var),
'total_std': torch.sqrt(total_var)
}
def calibrate_uncertainty(self, x_val, y_val):
"""
不确定性校准
校准曲线:期望置信度 vs 实际准确率
ECE = Σ (B_m * |acc(B_m) - conf(B_m)|)
"""
pred = self.predict_uncertainty(x_val)
# 按置信度分箱
confidence = 1 - pred['total_std']
predictions = pred['mean'].argmax(dim=-1)
accuracy = (predictions == y_val).float()
# 计算 ECE
n_bins = 10
ece = 0.0
bin_boundaries = torch.linspace(0, 1, n_bins + 1)
for i in range(n_bins):
mask = (confidence >= bin_boundaries[i]) & \
(confidence < bin_boundaries[i + 1])
if mask.sum() > 0:
bin_conf = confidence[mask].mean()
bin_acc = accuracy[mask].mean()
ece += mask.float().mean() * abs(bin_acc - bin_conf)
return ece.item()6. 与其他主题的联系
6.1 与消息传递神经网络的关系
消息传递神经网络(MPNN)与概率图模型中的信念传播有深刻联系。
6.1.1 MPNN 的概率解释
MPNN 的消息传递可以视为因子图上的消息传递:
其中 是可学习的势函数。
6.1.2 对应关系表
| MPNN 组件 | PGM 组件 | 形式化 |
|---|---|---|
| 消息 | 消息 | 邻居对当前节点的贡献 |
| 聚合 | 求和 | 边缘化邻居变量 |
| 更新 | 信念更新 | 结合自信息和传入消息 |
| 迭代层 | 消息步数 | 信息传播深度 |
6.2 与注意力机制的联系
Transformer 中的注意力机制可以从概率图模型角度重新解释。
6.2.1 软注意力作为归一化势函数
考虑自注意力的计算:
从概率图模型角度看:
- 势函数:
- 归一化常数:
- 消息:
- 归一化消息:
这与因子图上的置信传播具有完全相同的形式。
6.2.2 多头注意力的因子分解
多头注意力可以视为多个独立的因子图并行运行:
其中每个 对应一个独立的因子图结构,允许学习不同的依赖关系。
6.3 与扩散模型的联系
扩散模型(Diffusion Models)是深度概率模型的另一重要分支,与 VAE 有着深刻的联系。
6.3.1 扩散模型的概率图表示
扩散模型定义了一个两步概率图模型:
前向过程(编码):
其中
反向过程(解码):
其中 是神经网络近似的条件分布。
6.3.2 ELBO 与扩散模型
扩散模型的训练目标等价于最大化一个 ELBO:
分解:
6.3.3 与 VAE 的统一
VAE 和扩散模型可以统一在分数匹配变分推断的框架下:
| 方面 | VAE | 扩散模型 |
|---|---|---|
| 潜在维度 | 低维连续 | 高维(与数据同维) |
| 编码器 | 学习型 | 固定高斯(无参数) |
| 解码器 | 单步 | 多步迭代 |
| 采样速度 | 快(单步) | 慢(多步) |
7. 总结与展望
7.1 统一框架的核心要点
本文从概率图模型的角度重新审视神经网络,建立了以下对应关系:
┌─────────────────────────────────────────────────────────────────────┐
│ 统一框架总结 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 1. 结构对应: │
│ 神经网络层 ←→ 概率图模型的因子节点 │
│ 权重连接 ←→ 条件概率分布 │
│ │
│ 2. 推断统一: │
│ 前向传播 ←→ 消息传递 / 信念传播 │
│ 反向传播 ←→ 变分推断的梯度优化 │
│ │
│ 3. 学习统一: │
│ MLE/MAP ←→ 点估计(变分推断特例 β=0) │
│ VAE/BNN ←→ 变分推断(完整 ELBO) │
│ 扩散模型 ←→ 层次化变分推断 │
│ │
│ 4. 不确定性统一: │
│ 权重后验 ←→ 认知不确定性 │
│ 似然噪声 ←→ 偶然不确定性 │
│ │
└─────────────────────────────────────────────────────────────────────┘
7.2 前沿研究方向
- 更高效的变分推断:在大规模模型中,如何高效地进行变分推断?
- 深度概率模型:如何设计更好的层次化概率结构?
- 不确定性感知学习:如何在下游任务中有效利用不确定性?
- 概率电路:概率电路提供了一种可计算的统一表示
7.3 参考资料
相关主题:贝叶斯神经网络、变分推断深度解析、消息传递神经网络、概率图模型统一理论、扩散模型
Footnotes
-
Blei, D. M., Kucukelbir, A., & McAuliffe, J. D. (2017). Variational Inference: A Review for Statisticians. Journal of the American Statistical Association. ↩
-
Hoffman, M. D., Blei, D. M., Wang, C., & Paisley, J. (2013). Stochastic Variational Inference. Journal of Machine Learning Research. ↩
-
Jacot, A., Gabriel, F., & Hongler, C. (2018). Neural Tangent Kernel: Convergence and Generalization in Neural Networks. NeurIPS. ↩
-
Higgins, I., et al. (2017). -VAE: Learning Basic Visual Concepts with a Constrained Variational Framework. ICLR. ↩