思路
我认为的vae思路其实是因果关系:我们认为现实是果,我们想找因,找到这个因我们再弄清楚这个因是怎么产出果的就能随心所欲的创造出果了。
这里其实我们是在做推断,我们永远没有办法获得真实的
总结一下,我们目前有如下困难:
- 我们想要获得真实的后验,并且还得学会怎么用这个后验,所以:我们首先引入隐变量
,并使用 来参数化推断模型。 - 由于我们没有办法将分子对
进行积分,所以我们其实也没有办法得到 参数化的左侧。
对于困难 1
一切的源头都是对一个含有隐变量的分布进行参数估计。在这里,可观察变量是
ELBO
ELBO 的出现,是为了解决无法求得
右边就定义为ELBO,证据下界。
一般都会将联合概率写成条件概率的形式,因为条件概率是可算的:
第一项就是重构损失,第二项就是先验正则(控制不能离先验分布太远)
关键恒等式
有一个非常重要的等式,把三者连在一起:
由于KL散度总是非负的,所以这立刻揭示了为什么ELBO是下界,同时揭示了下界的松紧是由KL散度决定的。当
对于困难 2
我们又弄了一个
于是,我们的目标就是最小化 KL 散度,
变分是跟泛函相关的概念,指的是自变量函数的微小变化时,泛函值如何响应。例如变分法所关心的就是泛函极值问题,即找到最优的函数来让泛函取到最优值。

具体如何优化的 ?
计算梯度的时候也是分别对两个参数计算上述两个式子的梯度
重参数技巧,因为采样的动作是不可求梯度的,使得期望可以反向传播:
实际上就是输出两个参数,然后再使用
高斯分布的构造:If
,then
优化 ELBO时到底在做什么?
- 同时优化
和 :我们要最大化 (或者说最小化 )。简单说,就是在优化生成参数 的同时,用推断参数 去逼近真实的隐变量 的分布。 - 下界松紧性(tightness):随着
的优化, 会越来越接近真实后验, 变小,下界(ELBO)会更加紧致,也就是 会更接近真实的 NLL。 - EM 视角:E 步如果可行,就是直接用当前
下的真实后验做推断,M 步最大化期望完全数据对数似然。而在变分 EM 里,我们用 近似 E 步的真实后验,然后用 ELBO 进行联合优化。
为什么可以把目标定为优化 ELBO
上面我们推导了
那我们直接丢弃后面那个 KL 散度的计算是合理的么? 是合理的,合理性本质是由 EM 算法保证的。因为我们最大化 ELBO 是在交替迭代的做这两件事:
- 估计隐变量分布
或者是在做变分(式的)推断,因为我们的手段就是用 来逼近 ,是在优化编码器,因为此时要看成: 是固定的,我们优化的参数是phi(实际上训练vae不是,而是通过损失的平衡性自适应地调整)。因此, 是不变的,所以最大化ELBO就等价于最小化KL散度。此时我们对ELBO的优化只涉及到优化 ,所以本质上是给 找了一个更近的下界(这个下界也是 的函数,所以我们找了一个更好的函数,正所谓变分) - 计算似然损失对隐变量
的期望,然后再固定 ,优化 ,计算最大似然。其中计算似然损失对隐变量 的期望和第一件事合起来就对应EM算法的E步(Expectation),对应ELBO中的 ;而对 的优化(即ELBO)则对应EM算法中的M步(Maximum),可以分成两部分,一部分是作为重建项的条件似然,一部分是正则项,惩罚编码器拟合的后验 偏离我们假设先验 (实际上和 无关,被假设为标准高斯)的程度。此时, 是固定的、即编码器可以看成是固定的,于是我们的优化过程可以看成是在所找到的下界函数上找最大值。
为什么用高斯分布来引入 ?
因为是连续的,实际操作起来是可采样的

与复对数似然(NLL)的精确关系
由于 KL 散度
Vae的一些问题
后验坍塌(posterior collapse)
对于我们的目标函数,是由两项组成的:重建项+正则项
- 重建:期望
能够提供足够的信息,使得解码器能精准恢复 。它驱动 携带尽可能多的关于 的特征。 - 正则:期望后验分布
接近先验 p(z)(通常是标准正态分布)。它起到正则化作用,防止过拟合,但代价是可能会抹除 z 中携带的个性化信息 当解码器太强的时候,此时正则项趋近于 0.模型达到了一种虚假/消极的平衡。 - 自回归解码器的干预:如果你的解码器是一个非常强大的模型(例如 PixelCNN 或强力的 RNN/Transformer),它具有极强的自回归(Autoregressive)能力。即
在预测当前像素或单词时,仅靠 x 的历史信息就能完成得很好。 - 逻辑上的“捷径”:对于强解码器而言,去学习如何解析潜变量 z 是有成本的。如果解码器发现不需要 z 也能把重建项
做得很大,那么优化器为了最小化总损失,会倾向于让 KL 项直接归零。 - 编码器失效:此时编码器被“抛弃”了。无论输入什么 x,编码器都只输出先验分布以满足 KL 项的最小化。
解决方案
| 策略 | 逻辑原理 |
|---|---|
| KL Annealing | 在训练初期给 |
| Free Bits / KL Budget | 给 |
| 削弱解码器 | 使用非自回归解码器,强迫模型必须依赖 |
| 离散向量量化 (VQ-VAE) | 通过将 |
单流形的数据假设
比如在 mnist 任务上,假如在 z 空间对 0 到 1 进行插值,会发生奇怪的过渡数字,这个 ugly 的,因为这样的生成结果实际上对我们是没有用的。而发生这个的原因根本上是因为 模型假设 latent 是连通的,但真实数据不是。
# encoder: x -> (mu, logvar)# decoder: z -> x_hatdef interpolate(z1, z2, steps=10): ts = torch.linspace(0, 1, steps) zs = [(1 - t) * z1 + t * z2 for t in ts] zs = torch.stack(zs, dim=0) return zsx1, _ = dataset[0] # e.g. digit 0x2, _ = dataset[1] # e.g. digit 1
x1 = x1.unsqueeze(0).to(device)x2 = x2.unsqueeze(0).to(device)
mu1, _ = encoder(x1)mu2, _ = encoder(x2)
z1 = mu1.squeeze(0)z2 = mu2.squeeze(0)# 插值生成zs = interpolate(z1, z2, steps=10)with torch.no_grad(): recon = decoder(zs)