系列(一)|互信息 & 变分推理:你背过 ELBO,但你真懂它为什么存在吗


开头钩子

如果你学过 VAE,你一定见过这个公式:

ELBO=Eq(z∣x)[log⁡p(x∣z)]−DKL(q(z∣x)∥p(z)) \text{ELBO} = \mathbb{E}_{q(z|x)}[\log p(x|z)] - D_{\text{KL}}(q(z|x) \| p(z)) ELBO=Eq(zx)[logp(xz)]DKL(q(zx)p(z))

你也知道:

  • ELBO 是 Evidence Lower BOund
  • 最大化 ELBO ≈ 训练 VAE

但如果我问你:

“为什么一定要用 ELBO?为什么不能直接最大化 log p(x)?”

你是不是会卡住 3 秒?

👉 这说明你学的是"公式",不是"动机"。


这篇文章只解决一个问题

变分推理到底是怎么被"逼"出来的?


一、一切从一句大实话开始

我们想训练一个生成模型 p(x)p(x)p(x)

理论上,你应该最大化:

log⁡p(x) \log p(x) logp(x)

但:

p(x)=∫p(x,z) dz p(x) = \int p(x,z) \, dz p(x)=p(x,z)dz


❗这个积分是算不出来的

  • zzz 是高维隐变量
  • p(x,z)p(x,z)p(x,z) 是复杂的神经网络输出
  • 没有解析解
  • 数值积分直接爆炸

👉 所以 log p(x) 不可算


二、人类面对"算不出来"时的三条路

  1. 数值积分 → 高维直接跪
  2. MCMC 采样 → 准,但慢到工程上不能用
  3. 变分推理 → 不算它,换一个目标

三、变分推理的核心思维(请刻进 DNA)

我不算 p(z∣x)p(z|x)p(zx),我造一个 q(z∣x)q(z|x)q(zx) 逼近它。

  • p(z∣x)p(z|x)p(zx) 是真实后验(不可算)
  • q(z∣x)q(z|x)q(zx) 是我自己定义的近似后验(可算)

👉 这就是"变分"两个字的来源:函数空间里的优化


四、KL 散度的直觉(比定义重要)

DKL(q∥p)=Eq[log⁡q−log⁡p] D_{\text{KL}}(q \| p) = \mathbb{E}_{q}\left[ \log q - \log p \right] DKL(qp)=Eq[logqlogp]

翻译成人话:

KL = “你用 q 替代 p 会多损失多少信息”。


举个直觉例子

  • ppp:真实分布
  • qqq:你脑子里的猜测

👉 KL 小:说明你猜得很准
👉 KL 大:说明你在胡猜


五、关键问题来了(这里开始和所有教程不同)

我们想让 q(z∣x)≈p(z∣x)q(z|x) \approx p(z|x)q(zx)p(zx),自然想:

min⁡DKL(q(z∣x)∥p(z∣x)) \min D_{\text{KL}}(q(z|x) \| p(z|x)) minDKL(q(zx)p(zx))


但展开 p(z∣x)p(z|x)p(zx)

p(z∣x)=p(x,z)p(x) p(z|x) = \frac{p(x,z)}{p(x)} p(zx)=p(x)p(x,z)


❗p(x) 又出现了

👉 我们为了算 p(z|x),又撞上了那个算不出来的 p(x)。


六、变分推理最关键的一步代数(真正精华)

展开 KL:

DKL(q(z∣x)∥p(z∣x))=Eq(z∣x)[log⁡q(z∣x)−log⁡p(z∣x)]=Eq(z∣x)[log⁡q(z∣x)−log⁡p(x,z)+log⁡p(x)] \begin{aligned} D_{\text{KL}}(q(z|x) \| p(z|x)) &= \mathbb{E}_{q(z|x)}\left[ \log q(z|x) - \log p(z|x) \right] \\ &= \mathbb{E}_{q(z|x)}\left[ \log q(z|x) - \log p(x,z) + \log p(x) \right] \end{aligned} DKL(q(zx)p(zx))=Eq(zx)[logq(zx)logp(zx)]=Eq(zx)[logq(zx)logp(x,z)+logp(x)]


🔍 为什么 log p(x) 可以提出期望?

注意这个符号:

Eq(z∣x)[⋅]=∫q(z∣x)⋅(⋅) dz \mathbb{E}_{q(z|x)}[\cdot] = \int q(z|x) \cdot (\cdot) \, dz Eq(zx)[]=q(zx)()dz

👉 期望是对隐变量 zzz 求的,不是对 xxx

p(x)p(x)p(x) 是什么?边缘似然。它的定义是:

p(x)=∫p(x,z) dz p(x) = \int p(x,z) \, dz p(x)=p(x,z)dz

积分一做完,zzz 就没了。 所以 log⁡p(x)\log p(x)logp(x) 里面根本不含 zzz

对一个与积分变量无关的量求期望:

Ez∼q[C]=∫q(z)⋅C dz=C⋅∫q(z) dz=C \mathbb{E}_{z \sim q}[C] = \int q(z) \cdot C \, dz = C \cdot \int q(z) \, dz = C Ezq[C]=q(z)Cdz=Cq(z)dz=C

常数的期望,等于常数本身。


于是:

Eq(z∣x)[log⁡q(z∣x)−log⁡p(x,z)+log⁡p(x)]= Eq(z∣x)[log⁡q(z∣x)−log⁡p(x,z)]+Eq(z∣x)[log⁡p(x)]= Eq(z∣x)[log⁡q(z∣x)−log⁡p(x,z)]+log⁡p(x) \begin{aligned} &\mathbb{E}_{q(z|x)}\left[ \log q(z|x) - \log p(x,z) + \log p(x) \right] \\ =\ &\mathbb{E}_{q(z|x)}\left[ \log q(z|x) - \log p(x,z) \right] + \mathbb{E}_{q(z|x)}[\log p(x)] \\ =\ &\mathbb{E}_{q(z|x)}\left[ \log q(z|x) - \log p(x,z) \right] + \log p(x) \end{aligned} = = Eq(zx)[logq(zx)logp(x,z)+logp(x)]Eq(zx)[logq(zx)logp(x,z)]+Eq(zx)[logp(x)]Eq(zx)[logq(zx)logp(x,z)]+logp(x)


👉 重排后得到:

log⁡p(x)=Eq(z∣x)[log⁡p(x,z)−log⁡q(z∣x)]⏟ELBO+DKL(q(z∣x)∥p(z∣x)) \log p(x) = \underbrace{\mathbb{E}_{q(z|x)}\left[ \log p(x,z) - \log q(z|x) \right]}_{\text{ELBO}} + D_{\text{KL}}(q(z|x) \| p(z|x)) logp(x)=ELBO Eq(zx)[logp(x,z)logq(zx)]+DKL(q(zx)p(zx))


七、这一步的"顿悟解释"

盯住这个等式:

log p(x) = ELBO + KL


由于 KL ≥ 0:

ELBO≤log⁡p(x) \text{ELBO} \le \log p(x) ELBOlogp(x)

这就是 Evidence Lower Bound 的来源。


👉 更重要的是:

  • log⁡p(x)\log p(x)logp(x)qqq 来说是常数
  • 所以:

↑ELBO⇔↓DKL(q∥p) \uparrow \text{ELBO} \quad \Leftrightarrow \quad \downarrow D_{\text{KL}}(q \| p) ELBODKL(qp)


八、于是问题被彻底转化了

原始目标 问题 变分目标
min⁡DKL(q∣p)\min D_{\text{KL}}(q | p)minDKL(qp) ppp 不可算 max⁡ELBO\max \text{ELBO}maxELBO
不可算 完全可算

九、ELBO 为什么可算?(核心)

ELBO:

Eq(z∣x)[log⁡p(x,z)−log⁡q(z∣x)] \mathbb{E}_{q(z|x)}\left[ \log p(x,z) - \log q(z|x) \right] Eq(zx)[logp(x,z)logq(zx)]

每一项都是可算的:

  • log⁡p(x,z)\log p(x,z)logp(x,z):你定义的联合分布 =p(z)⋅p(x∣z)= p(z) \cdot p(x|z)=p(z)p(xz)
  • log⁡q(z∣x)\log q(z|x)logq(zx):你定义的近似后验(比如 encoder)
  • 期望:对 qqq 采样 zzz 后 Monte Carlo 估计

👉 真正不可算的只有 p(x)p(x)p(x),而 ELBO 成功绕开了它。


十、"期望"两个字,到底是怎么变成训练代码的?

你可能盯着 E\mathbb{E}E 心里发虚:

“我知道它是期望,可训练的时候电脑怎么算它?”


1️⃣ 期望符号的真实含义

Eq(z∣x)[f(z)]=∫f(z)⋅q(z∣x) dz \mathbb{E}_{q(z|x)}[f(z)] = \int f(z) \cdot q(z|x) \, dz Eq(zx)[f(z)]=f(z)q(zx)dz

在计算机里,我们几乎从来不算积分。我们用 Monte Carlo 估计

q(z∣x)q(z|x)q(zx) 里抽一堆 zzz 的样本,算出 f(z)f(z)f(z) 的值,然后取平均。


2️⃣ 用 VAE 的实际例子走一遍

假设你有一张输入图片 xxx(一张猫图)。

Step 1:Encoder 输出一个分布

Encoder 不是输出一个确定的 zzz,而是输出两个向量:

  • μ(x)\mu(x)μ(x)(均值)
  • σ(x)\sigma(x)σ(x)(标准差)

然后:

q(z∣x)=N(z;μ(x),σ2(x)) q(z|x) = \mathcal{N}(z; \mu(x), \sigma^2(x)) q(zx)=N(z;μ(x),σ2(x))

Step 2:从分布里采样 zzz

我们从这个高斯分布里抽一个具体的 zzz 向量,比如:

z = [0.23, -1.05, 0.87, ...]

Step 3:把 zzz 代入 log⁡p(x,z)\log p(x,z)logp(x,z) 算一个数

注意:p(x,z)=p(z)⋅p(x∣z)p(x,z) = p(z) \cdot p(x|z)p(x,z)=p(z)p(xz)

  • p(z)p(z)p(z) 是标准正态分布,把 zzz 代入公式算出对数概率密度
  • p(x∣z)p(x|z)p(xz) 是 decoder 输出分布,计算在真实 xxx 下的对数似然

于是你得到一个标量数值,比如 -3.42

Step 4:同时计算 log⁡q(z∣x)\log q(z|x)logq(zx)

把刚才采样的 zzz 代入 encoder 输出的高斯分布公式:

log_q_zx = -2.87

Step 5:得到这一个样本的 ELBO 贡献值

single_elbo_sample = log_p_xz - log_q_zx

3️⃣ 那期望呢?我只有一个样本啊!

在 SGD 训练中,我们通常只采一个 zzz(有时多个),然后用这一个样本的值作为期望的无偏估计。

即:

Eq(z∣x)[⋅]≈1L∑l=1L[log⁡p(x,z(l))−log⁡q(z(l)∣x)] \mathbb{E}_{q(z|x)}[\cdot] \approx \frac{1}{L} \sum_{l=1}^L \left[ \log p(x, z^{(l)}) - \log q(z^{(l)}|x) \right] Eq(zx)[]L1l=1L[logp(x,z(l))logq(z(l)x)]

实践中 L=1L=1L=1 非常常见。


4️⃣ 代码级直觉

# 输入:x (batch_size, input_dim)

# Encoder 输出分布的参数
mu, logvar = encoder(x)
std = exp(0.5 * logvar)

# 采样 z(重参数化)
eps = random_normal_like(mu)
z = mu + eps * std

# 计算 log q(z|x)
log_q = -0.5 * sum(1 + logvar - mu**2 - logvar.exp(), dim=1)

# Decoder 重建
x_recon = decoder(z)
log_p_x_given_z = log_likelihood(x, x_recon)

# 计算 log p(z)
log_p_z = -0.5 * sum(z**2, dim=1)

# log p(x,z)
log_p_xz = log_p_x_given_z + log_p_z

# ELBO 单个样本估计
elbo = log_p_xz - log_q

# 最终 loss 是负 ELBO
loss = -elbo.mean()

5️⃣ 一句必懂总结

“期望 Eq(z∣x)\mathbb{E}_{q(z|x)}Eq(zx)” 翻译成训练代码就是:
从 encoder 给出的分布里抽一个 zzz,算出目标值,然后把这当作整个期望的近似,扔进反向传播。


十一、ELBO 在干什么(物理直觉)

拆开 ELBO(另一种常见形式):

ELBO=Eq(z∣x)[log⁡p(x∣z)]−DKL(q(z∣x)∥p(z)) \text{ELBO} = \mathbb{E}_{q(z|x)}[\log p(x|z)] - D_{\text{KL}}(q(z|x) \| p(z)) ELBO=Eq(zx)[logp(xz)]DKL(q(zx)p(z))

  • 第一项:重建能力(要能解释数据)
  • 第二项:复杂度惩罚(不能让 qqq 太放飞)

👉 一句话总结 ELBO:

“既要解释数据,又不能乱猜隐变量。”


十二、为什么这是所有生成模型的地基

  • VAEqqq = encoder,ppp = decoder,直接优化 ELBO
  • β\betaβ-VAE:在 KL 项前面加系数 β\betaβ
  • 信息瓶颈(IB):ELBO 的约束变体

十三、一个你必须知道的边界

👉 什么时候变分推理会失效?

q(z∣x)q(z|x)q(zx)函数族太小,无论怎么优化 KL 都很大时。

这叫 approximation gap,是 VI 的结构性缺陷。


十四、可算性对照表

你要算的 可算吗 原因
p(x)p(x)p(x) 积分不可算
p(z∣x)p(z|x)p(zx) 分母是 p(x)p(x)p(x)
p(x,z)p(x,z)p(x,z) 你自己定义
q(z∣x)q(z|x)q(zx) 你自己定义
log⁡p(x,z)\log p(x,z)logp(x,z) 直接代值
Eq(z∣x)[⋅]\mathbb{E}_{q(z|x)}[\cdot]Eq(zx)[] Monte Carlo 采样
ELBO 全可算
DKL(q∣p(z∣x))D_{\text{KL}}(q | p(z|x))DKL(qp(zx)) p(z∣x)p(z|x)p(zx)
DKL(q(z∣x)∣p(z))D_{\text{KL}}(q(z|x) | p(z))DKL(q(zx)p(z)) p(z)p(z)p(z) 是先验

十五、总结

变分推理的核心思想是:
面对不可计算的真实后验 p(z∣x)p(z|x)p(zx),引入一个可计算的近似分布 q(z∣x)q(z|x)q(zx)
通过最小化两者 KL 散度,将问题转化为最大化 ELBO。
ELBO 是 log⁡p(x)\log p(x)logp(x) 的可计算下界,由重建项和正则项组成。
整个过程的数学合法性建立在 log⁡p(x)=ELBO+DKL(q∥p)\log p(x) = \text{ELBO} + D_{\text{KL}}(q \| p)logp(x)=ELBO+DKL(qp) 这个恒等式上。


Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐