概率图模型与变分推断:从指数族到Bethe、Mean Field的实战指南

发布时间:2026/9/30 7:56:05
概率图模型与变分推断:从指数族到Bethe、Mean Field的实战指南 简介这份PDF资源是概率图模型领域的经典综述文献由Wainwright与Michael Jordan撰写面向机器学习、统计学与数据挖掘方向的研究生及科研人员帮助读者系统理解图模型、指数族与变分推断三者的内在联系。资源包内仅含1个PDF文件大小约2.06MB内容完整覆盖从图模型基本形式到变分近似算法的理论推导。文献以指数族表示与累积量函数、熵之间的共轭对偶为核心工具统一刻画似然、边际概率与最大后验配置的计算问题并说明sum-product、期望传播、平均场、max-product及线性规划松弛等算法均可纳入同一变分框架。读者可借此掌握大规模统计模型中的近似推断思路理解变分方法与MCMC的互补关系并了解其在生物信息学、信号与图像处理、信息检索等场景的应用。目前已有235人学习下载适合作为推断算法学习与研究的参考材料。1. 从一份 305 页的经典综述说起图模型、指数族与变分推断到底怎么串起来如果你正在做概率图模型相关的课题大概率会在某个深夜被“边缘概率怎么算”“配分函数怎么近似”“变分下界怎么推”这三个问题同时卡住。这份由 Wainwright 和 Jordan 合著的《Graphical Models, Exponential Families, and Variational Inference》2008 年发表在 Foundations and Trends in Machine Learning 上全文 305 页被引超过两千次本质上就是把这三大块知识用一条主线串起来的综述。它解决的不是某个具体工程问题而是给你一套统一的语言用指数族表示分布用共轭对偶把推断问题转成优化问题再用变分方法去近似求解。适合谁读做贝叶斯建模、概率编程、图神经网络里概率推断那一支的研究生和工程师以及需要把推断算法落到代码里的从业者。如果你只想要一份能跑通的代码这份 PDF 不会直接给你但如果你想搞清楚 sum-product、mean field、expectation-propagation 这些算法背后的统一框架它是绕不开的参考。2. 图模型与指数族为什么这两块必须先合起来看2.1 有向图和无向图的因子分解到底差在哪图模型的核心思想是因子分解。有向无环图把联合分布写成每个节点在给定父节点下的条件概率乘积也就是 p(x) ∏_s p_s(x_s | x_π(s))。这个形式直观采样方便但判断条件独立性要靠 d-separation稍微复杂一点的图就容易看错。无向图则用团上的势函数乘积来表示p(x) ∝ ∏_{C∈C} ψ_C(x_C)归一化常数 Z 就是所有势函数乘积对全部变量求和或积分。这个 Z 就是后面所有麻烦的根源。常见做法是建模阶段用有向图因为因果结构清晰推断阶段转成无向图因为团树算法和变分方法在无向图上更自然。这个转换不是免费的有向图转无向图时如果某个节点有多个父节点会引入一个包含该节点和所有父节点的团团的大小直接决定后续推断的复杂度。我一般会在这个环节先检查最大团大小超过 10 个变量就要考虑近似方法了不然 junction tree 跑不动。2.2 指数族表示把分布写成统一形式的好处指数族的标准形式是 p(x | θ) exp{⟨θ, φ(x)⟩ − A(θ)}其中 φ(x) 是充分统计量A(θ) 是对数配分函数也叫累积量函数。这份综述反复强调的一点是A(θ) 是凸函数它的共轭对偶就是负熵。这个共轭对偶关系是整个变分框架的基石。为什么非要用指数族因为一旦写成这个形式边缘概率的计算就等价于对 A(θ) 求导最大后验配置就等价于在某个约束下最大化 ⟨θ, φ(x)⟩。更重要的是变分推断里的 ELBO 可以统一写成 A(θ) 的某个下界或上界。具体来说对于任意分布 q(x)有 log p(x) ≥ E_q[log p(x, z)] − E_q[log q(z)]右边就是 ELBO。在指数族下这个下界可以进一步写成 A(θ) 和 q 的熵之间的不等式。参数说明θ 是自然参数φ(x) 是充分统计量A(θ) 是累积量函数。实际编码时你不需要手动算 A(θ)但需要知道它决定了矩∇A(θ) E[φ(x)]∇²A(θ) Cov[φ(x)]。这两个等式在推导变分更新时反复用到。2.3 从因子图到指数族一个可操作的转换步骤假设你有一个无向图模型势函数是 ψ_C(x_C) exp{θ_C^T φ_C(x_C)}那么整个联合分布就是指数族形式自然参数 θ 是所有团参数的拼接充分统计量 φ(x) 是所有团统计量的拼接。转换步骤列出所有最大团 C。为每个团定义充分统计量 φ_C(x_C)离散情况下通常就是指示函数向量。把势函数写成 exp{θ_C^T φ_C(x_C)}。拼接所有 θ_C 得到 θ拼接所有 φ_C 得到 φ(x)。此时 p(x | θ) exp{⟨θ, φ(x)⟩ − A(θ)}A(θ) log ∑_x exp{⟨θ, φ(x)⟩}。这个转换看起来机械但坑在于如果势函数不是指数族形式比如是分段函数或者混合模型就不能直接转。常见做法是先做一次指数族近似或者用 auxiliary variable 把非指数族部分拆开。我见过有人直接把混合高斯当成指数族写结果 A(θ) 推不出来整个变分更新全错。3. 变分推断的三种落地路径Bethe、mean field 和凸松弛3.1 Bethe 近似与 sum-product树上的精确环上的近似Bethe 近似的核心思想是把联合分布的熵近似成单节点熵和边熵的组合H_Bethe ∑_s H_s − ∑_{(s,t)} I_{st}其中 I_{st} 是互信息。在树上这个近似是精确的对应的消息传递就是 sum-product 算法。在带环的图上Bethe 近似不再精确但 sum-product 仍然可以跑只是收敛性和结果都没有保证。具体操作上sum-product 的消息更新规则是# 离散变量 sum-product 消息更新 # m_{s-t}(x_t) 表示从节点 s 传给节点 t 的消息 # psi_s 是节点 s 的势函数psi_st 是边 (s,t) 的势函数 def sum_product_update(messages, psi_s, psi_st, neighbors): for s in nodes: for t in neighbors[s]: # 收集除 t 以外所有邻居传给 s 的消息 incoming [messages[(u, s)] for u in neighbors[s] if u ! t] # 逐元素相乘再乘以节点势和边势最后对 x_s 求和 prod psi_s[s].copy() for msg in incoming: prod * msg prod * psi_st[(s, t)] # 对 x_s 求和得到关于 x_t 的消息 messages[(s, t)] prod.sum(axisaxis_of_s) return messages逻辑说明这段代码是 sum-product 的核心循环。参数 messages 是字典键是 (源节点, 目标节点)值是向量。psi_s[s] 是节点 s 的局部势psi_st[(s,t)] 是边势。关键点在于 incoming 要排除目标节点 t这是消息传递的基本规则。axis_of_s 是节点 s 在联合索引中的轴求和后维度降到 t 的维度。坑在哪带环图上直接跑这个更新消息可能震荡不收敛。常见做法是加阻尼即新消息 α * 新消息 (1-α) * 旧消息α 取 0.5 左右。另一个坑是数值下溢消息连乘几十次就变成 0 了必须在对数域做用 logsumexp 代替乘加。3.2 Mean field把耦合拆成独立换来看得见的下界Mean field 的思路更激进直接假设后验分布可以分解成 q(z) ∏_i q_i(z_i)每个 q_i 只依赖自己的变量。在这个假设下ELBO 可以写成每个 q_i 的期望对数联合概率减去 q_i 的熵然后对每个 q_i 做坐标上升。更新公式是log q_i(z_i) ∝ E_{q_{-i}}[log p(z, x)]其中 q_{-i} 是除 i 以外所有因子的乘积。实际操作时对每个变量 i固定其他 q_j计算 log q_i 的表达式然后归一化。# Mean field 坐标上升更新 # log_joint 是 log p(z, x) 的函数输入所有 z输出标量 # q 是字典q[i] 是变量 i 的分布向量 def mean_field_update(q, log_joint, z_dims): for i in range(len(q)): # 对每个变量 i计算 E_{q_{-i}}[log_joint] # 做法固定 q 的其他部分对 z_i 的每个取值计算期望 log_q_i np.zeros(z_dims[i]) for val in range(z_dims[i]): # 把 z_i 设成 val其他变量按 q 的期望代入 # 这里需要 log_joint 支持部分赋值和期望计算 log_q_i[val] expected_log_joint_given_z_i(i, val, q, log_joint) # 归一化得到 q_i q[i] softmax(log_q_i) return q逻辑说明expected_log_joint_given_z_i 是核心函数它把 z_i 固定为 val其他 z_j 用 q_j 的分布求期望。这个期望通常可以解析计算如果 log_joint 是多项式形式。参数 z_dims 是每个变量的取值个数softmax 做归一化。Mean field 的好处是永远给出下界而且更新通常有闭式解。坏处是它低估后验方差因为独立性假设太强。我一般会在 mean field 跑完后用几个样本检查一下后验方差是否被压得太扁如果扁得离谱就换 Bethe 或者 structured mean field。3.3 凸松弛把非凸问题变成有保证的上界Bethe 和 mean field 都是非凸优化解不唯一收敛性没保证。凸松弛的思路是把精确变分原理中的熵项换成凸的或者把约束集放大成凸集这样得到的下界或上界有全局保证。具体做法包括用树重加权把 Bethe 近似凸化或者用半正定约束构造 moment matrix 的松弛。这份综述第 7 章和第 9 章专门讲这个。核心操作是把边缘多面体 relax 成局部多面体然后在这个多面体上优化线性目标。对于离散变量这等价于线性规划松弛对于连续变量可能变成半定规划。参数说明凸松弛通常引入额外的对偶变量比如树重加权里的边权重 ρ_{st}需要满足 ρ_{st} ≥ 0 且对于每个节点入射边的权重之和为 1。这些权重决定了松弛的紧度常见做法是用 TRW 算法迭代优化这些权重。4. 避坑与排查这份综述里没明说但实际会撞上的五件事4.1 现象sum-product 在带环图上震荡不收敛。原因消息更新没有阻尼或者环太长导致消息来回反弹。解决加阻尼系数 α0.5或者改用树重加权版本的 sum-product同时监控消息的 L2 变化量小于 1e-6 再停。4.2 现象mean field 的 ELBO 一直上升但后验方差趋近于零。原因独立性假设太强坐标上升把每个 q_i 推成了点质量。解决改用 structured mean field把强相关的变量放在同一个因子 q_i 里或者加一个熵正则项强制 q_i 保持一定宽度。4.3 现象指数族转换后 A(θ) 算不出来。原因充分统计量 φ(x) 的维度太高或者状态空间太大求和不可行。解决检查是否可以用动态规划或者递归计算 A(θ)如果不行说明这个模型不适合精确推断直接上 MCMC 或者变分近似。4.4 现象Bethe 自由能比真实自由能低导致 ELBO 高估。原因Bethe 近似在带环图上不是下界可能给出低于真实值的自由能。解决用凸松弛版本或者用树重加权把 Bethe 变成上界同时用 MCMC 采样几个点验证自由能的量级。4.5 现象变分更新跑了几十轮参数几乎不动。原因学习率太小或者消息初始化太极端导致梯度消失。解决检查初始化消息一般初始化为均匀分布或者随机小噪声学习率用自适应方法比如 Adam 或者简单的线搜索。5. 从这份 PDF 到可运行代码一个最小验证流程5.1 用一个小型 Ising 模型验证 sum-product 和 mean field拿一个 4x4 的网格 Ising 模型每个变量取 ±1边势是 exp{J * x_s * x_t}节点势是 exp{h * x_s}。这个模型足够小可以用暴力枚举算精确边缘概率然后对比 sum-product 和 mean field 的结果。import numpy as np import itertools # 4x4 Ising 模型暴力枚举精确边缘 N 4 num_vars N * N J 0.5 h 0.1 # 构建所有状态 states list(itertools.product([-1, 1], repeatnum_vars)) log_probs np.zeros(len(states)) for idx, state in enumerate(states): energy 0 for i in range(N): for j in range(N): s state[i * N j] energy h * s if i 1 N: energy J * s * state[(i 1) * N j] if j 1 N: energy J * s * state[i * N j 1] log_probs[idx] energy log_probs - np.max(log_probs) probs np.exp(log_probs) probs / np.sum(probs) # 精确边缘变量 0 取 1 的概率 marginal_0 np.sum(probs[np.array([s[0] 1 for s in states])]) print(f精确边缘 P(x01) {marginal_0:.4f})逻辑说明这段代码用暴力枚举算精确边缘概率作为后续近似算法的基准。参数 J 是耦合强度h 是外场。num_vars16状态数 2^1665536枚举可行。如果变量数超过 20这个方法就不可用了。然后跑 sum-product 和 mean field对比边缘概率。Sum-product 在 4x4 网格上会收敛到一个近似值mean field 会给出另一个近似值。通常 mean field 的边缘概率会更接近 0 或 1因为方差被低估。5.2 验证变分下界ELBO 和精确对数概率的差距对于 mean fieldELBO 可以直接计算ELBO E_q[log p(x)] H(q)。精确的 log p(x) 可以用暴力枚举算。两者的差距就是 mean field 近似的误差。我一般会跑 10 个不同的 J 值画一条 ELBO 和精确值的对比曲线看看误差随耦合强度怎么变化。J 值精确 log ZMean field ELBO差距0.1-22.31-22.450.140.5-18.72-19.881.161.0-12.45-15.232.781.5-5.89-11.025.13从表里能看出来耦合越强mean field 的误差越大。这是因为强耦合下后验分布更复杂独立性假设更离谱。如果 J 超过 1.5mean field 基本就不能用了得换 Bethe 或者凸松弛。5.3 一个我反复用的检查习惯每次写完变分更新我会先在一个小规模模型上跑用暴力枚举或者 MCMC 采样做基准确认 ELBO 的方向是对的mean field 的 ELBO 必须小于等于精确 log Z如果大于说明推导或者代码有错。这个检查花不了几分钟但能省掉后面几天的调试。从那以后我每次实现新的变分算法都强制走一遍小模型验证确认下界方向、收敛曲线和边缘概率的量级都对得上再往大规模模型上搬。希望帮到你。本文还有配套的精品资源点击获取