简介:这份PDF是面向机器学习、统计推断与概率建模方向研究者及研究生的经典综述,聚焦概率图模型、指数族与变分推断三者的统一框架,适合已具备一定概率论基础、希望系统理解大规模多元统计模型推断算法的读者。内容从指数族表示与累积量函数—熵的共轭对偶出发,给出似然、边际概率与最大后验构型的变分表达,并串联和积算法、聚类变分、期望传播、平均场、最大积、线性规划与锥规划松弛等方法,也将其与MCMC近似作互补讨论。压缩包仅含1个PDF文件,大小约2.06MB,轻量便于检索与随身阅读。目前已有235人学习,可作为课程研讨、论文写作或算法实现前的理论索引,帮助读者建立从图结构、指数族参数化到变分近似的完整知识脉络。
1. 概率图模型到底是什么:一张画满圆点和连线的关系网
一个班五十个学生,期末成绩彼此关联,想完整描述这五十个分数一起出现的概率,理论上得填一张五十维的大表格,大到没地方存。概率图模型(简称图模型)干的事,就是把这张填不完的表格拆成一张关系网:每个学生画成一个圆点,两个点之间连一条线,表示“这两人的分数直接相关”,然后规定整个联合概率就是这些局部关系的乘积。圆点叫节点,连线叫边,图论负责描述形状,概率论负责给每个形状配上数值。这么一拼,就得到一个既能表达复杂依赖、又不至于算到天荒地老的建模工具。它是后面指数族、变分推断整套叙事的地基,把这块搞明白,剩下的部分就只是在这张网上做运算了。
2. 为什么把概率画成图:因子分解才是真正的省钱办法
2.1 联合分布爆炸:不拆就没法算
先算笔账。假设有 50 个只取 0 和 1 的变量,要完整描述它们的联合分布,得给 2 的 50 次方种组合各配一个概率值,扣掉归一化剩 2^50 − 1 个自由参数。这个数字约为 10 的 15 次方,存不下,更标不出来。现实里的变量还远不止二值,取值一多,组合数飞得更快。所以问题从来不是“模型够不够复杂”,而是“参数能不能塞得进内存”。
图模型的解法是引入假设:变量之间不是两两都相关,而是大部分互相无关。一旦承认这件事,联合分布就能按图的结构拆成一串局部因子的乘积。举个最朴素的例子,如果五个变量排成一条链,每个只依赖前一个,那么联合分布写成 p(x₁)p(x₂|x₁)p(x₃|x₂)p(x₄|x₃)p(x₅|x₄),参数从 2⁵ − 1 = 31 个掉到 1 + 4×2 = 9 个。50 个变量的链呢?1 + 49×2 = 99 个。参数从指数级变成线性级,靠的不是近似,而是那条“谁跟谁直接相连”的假设。
这里要留个心眼:参数省下来的代价是表达能力变弱。图里没有边,等价于你主动宣称“这两个变量在给定其他变量后条件独立”。这个宣称对不对,是建模者的责任,不是算法的责任。图模型从来不负责替你判断因果结构,它只负责在你给出结构之后,把计算变得可行。
2.2 有向图与无向图:箭头和连线分别在说什么
同样是画网,两种画法的语义不一样。有向图要求无环,每条边带方向,从父节点指向子节点,联合分布写成每个节点“在给定父节点时的条件概率”之积。这种结构适合描述有生成顺序的过程:先有因,后有果,因果关系或者时间先后比较明确,比如症状由病因决定、观测由隐状态产生。
无向图没有方向,只有连接,联合分布写成定义在“团”上的势函数之积,再除以一个归一化常数。它适合描述对称的、没有明确先后顺序的相互影响,比如一张图像里相邻像素的平滑约束,或者两个人在同一时刻的相互影响——你说不清谁先谁后,但知道它们相关。
拿一段极小的代码把有向图的因子分解落到实处,会更容易看清“省”在哪里。
# 四个变量的有向图:1、2、3 都是 4 的父节点 # 联合概率 = 各节点条件概率的乘积,不做任何全表枚举 def joint(x1, x2, x3, x4, p1, p2, p3, p4_given_123): return ( p1[x1] * # 根节点,只用边缘表 p2[x2] * # 根节点,只用边缘表 p3[x3] * # 根节点,只用边缘表 p4_given_123[(x1, x2, x3)][x4] # 条件表,按父节点取值索引 )这段函数没有存 2⁴ = 16 个联合概率,而是存了 2 + 2 + 2 + 8 = 14 个局部数值。变量少的时候看不出便宜,把节点数推到 30、每个节点三个父节点,差距就是天壤之别。函数里每个参数表的语义很清楚:p1、p2、p3是边缘分布,最后一个二维字典p4_given_123的第一层键是父节点的取值组合,第二层键是节点 4 自己的取值。改动父节点集合,只需改这张条件表的键,其余代码不动。
无向图则换个写法,用势函数表达“这几个变量凑在一起有多相容”,最后整体归一化。势函数不必是概率,只要非负即可,归一化常数负责把它拉回概率。这也解释了为什么无向图里的参数不好直接解释成概率——它们描述的是相对偏好,不是发生频率。
2.3 从图上看条件独立:d-分离与那个容易被忽略的 V 型结构
图模型真正值钱的地方,是让“条件独立”这件事可以肉眼读出来。无向图里判断很简单:把要观测的变量从图里删掉,如果两个节点之间再无路径,它们在给定这些变量后条件独立。有向图要用 d-分离,规则稍绕,核心是三种三节点结构。
链式结构 A → B → C,观测 B 就切断了 A 和 C 的联系。分叉结构 A ← B → C 同理,观测 B 之后 A、C 独立。最反直觉的是第三种,V 型结构 A → C ← B:A 和 B 本来独立,可一旦观测了共同子节点 C,它们反而变得相关。下雨和洒水车都指向“地面湿”,地面湿这件事被看到之后,你推断“下雨了”,就会下调“洒水车开过”的概率——两者通过共同结果产生了竞争关系。这个现象常被叫作 explaining away,是贝叶斯网络里最容易翻车的地方。
很多初学者以为“图上没边就等于独立”,这是把边缘独立和条件独立混成一锅。正确的读法是:没边说明在给定某组变量后独立,而“给定谁”恰恰由结构决定,V 型结构里那组变量是子节点而不是父节点。同样的图,观测集合不同,独立结论可以完全相反。
3. 指数族:为什么一大半常见分布都是“一家人”
3.1 一个模板套住伯努利、高斯和泊松
指数族不是某一个分布,而是一类分布的写法模板:p(x|θ) = h(x)·exp(⟨θ, T(x)⟩ − A(θ))。这里 θ 是自然参数,T(x) 是充分统计量,A(θ) 是对数配分函数,h(x) 是底层测度。把它看成一句话:任何能用“统计量的线性组合再取指数”描述的分布,都归这一家。
伯努利分布套进去,T(x) = x,θ 是 logit 形式的对数几率,A(θ) = log(1 + e^θ)。高斯分布(固定方差)套进去,T(x) = (x, x²),θ 是均值和方差对应的两个参数。泊松分布套进去,T(x) = x,θ = log λ。除此之外,多项分布、伽马分布、贝塔分布、狄利克雷分布、指数分布全在族内。机器学习里大部分常见似然都能写成这个形状,这不是巧合。
统一写法带来的是统一推导。只要证明一个结论对指数族成立,它就是几十个分布的共同财产,不用一个个重来。共轭先验为什么长那样、广义线性模型为什么用链接函数、变分推断为什么能写成凸优化,答案都藏在这个模板里。对刚接触的人来说,最实用的一点是:看到“指数族”三个字,先别想成某个具体分布,先想成“能不能塞进这个模板”。
3.2 对数配分函数:那个凸函数为什么这么关键
A(θ) 看着像个为了归一化硬凑出来的项,其实是整个族的信息中枢。对 θ 求一阶导,得到充分统计量的期望;求二阶导,得到充分统计量的协方差。换句话说,分布的矩信息全被这一个函数打包了,求导就能取出来。
更关键的是,A(θ) 是凸函数。凸意味着求极值有全局保证,意味着可以用切线、用对偶、用一系列成熟的优化工具去处理它。指数族之所以在统计和机器学习里地位特殊,很大程度上就是因为这个凸性:模型的对数似然是凹的,参数的估计问题是个漂亮的凸问题,不会陷进局部最优。
打个比方,A(θ) 像一台自动售货机:你投进去参数 θ,它吐出来归一化常数;你按一下“求导”按钮,它吐出来均值;按两下,吐出来方差。所有矩都能从这一个入口取,不用重新推积分。这一层便利,是后面变分推断能把“算积分”翻译成“解优化”的前提。
3.3 共轭对偶:把算积分翻译成解优化
有了凸函数,就能取共轭对偶。A(θ) 的共轭对偶 A*(μ) 定义为在所有 θ 上取 ⟨θ, μ⟩ − A(θ) 的上确界,而这个对偶函数恰好就是负熵。反过来写,A(θ) 等于在所有合法的均值参数 μ 上取 ⟨θ, μ⟩ − A*(μ) 的上确界。
这行式子是整个变分方法的源头。它说的是:一个原本要算积分才能得到的数,可以改写成“在某个集合上求最大值”的问题。求最大值比算高维积分好办得多,因为优化有成熟的迭代算法、有收敛判据、有对偶间隙可以监控。原文把这一层叫共轭对偶,通俗地说,就是给积分找了个“优化版替身”。
变分推断里“变分”两个字,指的就是这种把数值写成极值问题的操作。理解了这一点,后面看到 ELBO、看到平均场、看到 Bethe 近似,就不会觉得是一堆互不相干的技巧,而是同一个套路在不同精度下的展开。
4. 变分推断:把算不动的积分换成一个能解的优化题
4.1 精确推断什么时候会翻车:树宽是那条硬线
图上要算的两类基本量:边缘概率(含似然)和最可能配置(模式)。树结构的图有精确算法,和积算法沿着树做两遍消息传递,复杂度与节点数成正比,干净利落。一般的图没这么好运,得先把图三角化、构造联合树,再在联合树上跑同样的消息传递。麻烦在于,联合树里每个团的大小由图的树宽决定,计算量随树宽指数增长。
树宽小,比如一条链、一棵树、或者稀疏的环形结构,精确推断跑得动。树宽一大,比如一张几百乘几百像素的图像网格,每个像素跟上下左右四个邻居相连,树宽会随边长线性增长,指数一上去,精确算法立刻趴窝。这就是“图看起来稀疏,但推断仍然算不动”的典型场景,也是近似方法存在的全部理由。
一条实用的判断线是:先估树宽,再看它能不能压到十几以内。压得住就走精确路线,压不住就老老实实上近似。跳过这一步直接调近似算法,很容易在本来有精确解的小图上折腾半天,得到还不如精确解的答案。
4.2 ELBO 与 KL 散度:逼近的方向为什么不能反
变分推断的标准做法,是挑一个形状简单、容易处理的分布 q,让它去贴近真实后验 p(z|x)。衡量贴近程度用 KL 散度,但这里有个方向问题:算 KL(q‖p) 需要对 q 求期望,q 是自己选的,采样方便;算 KL(p‖q) 要对 p 求期望,而 p 正是那个算不出来的东西。所以只能是前者。
把 log p(x) 拆开,会得到 log p(x) = ELBO(q) + KL(q‖p(z|x))。KL 非负,于是 ELBO 是 log 证据的下界,最大化 ELBO 等价于最小化 KL(q‖p)。这个下界就是变分推断的目标函数,训练时盯着它涨就行。要注意 KL(q‖p) 这种方向有个著名脾气:它倾向于让 q 覆盖后验的多个峰,而不是死盯一个峰。放到平均场假设下,变量被强行拆成独立,q 往往会低估后验的方差,这一点在做不确定性量化时得留神。
平均场的求解用坐标上升,轮流更新每个变量的近似分布,固定其余变量不动。
# 平均场坐标上升:轮流优化每个变量的近似分布 q[j] for sweep in range(max_sweeps): elbo_old = compute_elbo(q) # 记录本轮起点 for j in range(num_vars): # 固定除 j 以外的所有 q,用它们的期望算 j 的局部更新 q[j] = update_factor(observed, q, j) elbo_new = compute_elbo(q) if elbo_new - elbo_old < tol: # ELBO 单调不减,可作收敛判据 break三个参数值得说明:max_sweeps是外层轮数上限,防止不收敛时死循环;tol是收敛阈值,取太小会白烧算力,取太大会提前停;update_factor是局部更新公式,不同的模型只是换这一个函数,框架不变。ELBO 单调不减这条性质很实用,它是坐标上升的必然结果,意味着曲线一旦不涨了就是真收敛,不会出现来回震荡的假象。
4.3 平均场、Bethe 近似与信念传播:三种近似的脾气
同样是近似,几种方法的取向差别不小。平均场把后验拆成完全独立的乘积,牺牲相关性换取可解性,优化问题是凸的、收敛稳定,代价是方差被系统性低估。Bethe 近似保留了边上的成对相关性,在树上精确、在有环图上是近似,和积算法(信念传播)的不动点方程正是它的驻点条件。麻烦在于 Bethe 目标函数一般非凸,消息传递可能不收敛,也可能振荡。
再往上一层是凸松弛,比如树重加权、对数行列式松弛,把非凸的近似目标换成凸的,代价是解出来的是界而不是点估计,计算量也更大。原文把这几类方法放在同一套变分表示下统一处理,好处是能一眼看出谁在近似什么。
| 方法 | 保留的相关性 | 优化性质 | 典型输出 |
|---|---|---|---|
| 平均场 | 几乎不保留 | 凸,稳定收敛 | 下界,方差偏小 |
| Bethe 近似 | 边上成对 | 非凸,可能振荡 | 近似值,方向不保证 |
| 凸松弛 | 可控地保留 | 凸,可解 | 上界或下界,视构造而定 |
选哪种,取决于你更怕哪件事:怕不收敛就选平均场,怕方差估小就上 Bethe 或凸松弛,怕没有误差保证就走向凸的那一侧。没有一种方法全面胜出,这也是为什么资料里要把它们并排讲,而不是只推一种。
5. 容易搞混的几对概念:把边界划清楚
5.1 有向图的箭头不等于因果关系
易混点在于箭头长得就像“导致”,很多人看一眼就把有向图当因果图用。之所以混,是因为有向图确实常常按因果顺序来建,父节点写在子节点前面,看着顺理成章。区分办法是看它到底编码了什么:有向图编码的是条件独立关系,只要联合分布能按这个顺序分解,箭头方向怎么写都成立,同一组独立关系可以有多个等价的有向图。要做因果结论,得额外引入干预、混杂因子处理那一整套假设,光有一张图不够。把有向图当因果图,属于把“能分解”误读成“能干预”。
5.2 指数族不等于指数分布
这两个词共享两个字,混淆率极高。指数分布是一个具体分布,描述等待时间,只有一个参数;指数族是一大类分布的统称,成员包括高斯、伯努利、泊松、伽马、狄利克雷等几十个。之所以混,纯粹是中文译名撞车。区分办法很简单:看到“族”字就想成“模板”和“集合”,看到“分布”就想成“单个成员”。判断某个分布属不属于指数族,套模板试一下就知道,套得进去就是,套不进去就不是,跟它名字里有没有“指数”毫无关系。
5.3 变分推断不等于 MCMC:一个有偏一个无偏
两者都是近似推断的手段,目标都是后验,但路子完全相反。MCMC 靠采样,样本够多时渐近精确,代价是慢,而且很难判断“够多了没有”;变分推断靠优化,速度快、能处理大规模数据,但结果有系统偏差,给的是近似而非真值。之所以混,是因为初学者常把“近似推断”当成一个整体,以为选哪个都差不多。区分办法看需求:要严格的误差保证和准确的方差,走 MCMC;要快、要能嵌进训练循环、要对超大规模数据做在线更新,走变分。二者也不是非此即彼,混合使用很常见。
5.4 图模型不等于神经网络
图模型是描述变量依赖结构的框架,重点在“谁能影响谁”和“怎么算边缘概率”;神经网络是参数化的函数逼近器,重点在“怎么拟合一个映射”。之所以混,是因为图神经网络这类东西把两个词拼在了一起,让人以为是一回事。区分办法看输出:图模型的输出是概率分布、边缘概率、最可能配置;神经网络的输出是向量、分数、预测值。二者可以结合,用神经网络参数化图模型里的势函数是常见做法,但结合不等于等同。
6. 什么时候该用这套东西:三条判断线和一次踩坑
落到实操,问三个问题基本就能定位。第一个问题:变量之间的依赖结构清不清楚、能不能画出来?能画出来,图模型就有用武之地;画不出来、只想拟合一个从输入到输出的映射,那大概率该用别的东西。第二个问题:树宽压不压得住?压得住走精确推断,压不住才考虑近似。第三个问题:你要的是点估计还是带不确定性的分布?只要点估计,模式计算(max-product 那一支)往往比求边缘更省事;要分布,就得在平均场、Bethe、凸松弛之间按前面说的脾气挑。
| 场景 | 建议路线 | 需要警惕的地方 |
|---|---|---|
| 结构稀疏、树宽小 | 联合树精确推断 | 三角化顺序影响树宽,别随手排 |
| 结构稠密、要快速出结果 | 平均场 | 方差被低估,别拿它做区间估计 |
| 有环但稀疏、要精度 | Bethe 近似或凸松弛 | 消息传递可能不收敛,要设迭代上限 |
| 变量全是离散、只求最可能配置 | max-product 加线性规划松弛 | 松弛解不一定整数,要做取整校验 |
我自己踩过的一个坑,是在一张看着挺稀疏的网格图上直接上精确推断,心想边数不多应该没事,结果跑了一晚上内存直接爆掉。后来才老老实实先估树宽,发现它随网格边长线性涨,压根压不住。从那以后我每次拿到一张图,第一件事都是先算树宽和最大团大小,再决定走哪条路,这一步花不了几分钟,能省掉一整晚的无效计算。
反过来,也有不该用的时候。样本量极小、结构完全靠猜,硬套图模型只会把错误的独立性假设固化进结果里,这时候简单的正则化模型反而更稳。变量数很少、联合分布直接枚举就行,也别为了用框架而用框架。这套东西真正的价值,是在变量多、依赖复杂、又必须给出概率量的时候,把不可算变成可算。
这份资料把图模型、指数族、变分推断三条线串在同一个变分表示下讲,从因子分解一路推到平均场、Bethe 近似和凸松弛,还单独讨论了参数估计和模式计算,适合想把这套东西一次理顺的人。需要完整内容的话,按文末方式获取即可。希望帮到你。
本文还有配套的精品资源,点击获取