变分自编码器 VAE 超详解:从简单公式推导到模型结构到模型理解
变分自编码器 VAE 超详解:从简单公式推导到模型结构到模型理解
变分自编码器(VAE)是一种强大的生成模型,它通过引入概率分布的概念,将传统的自编码器升级为能够生成新样本的模型。本文将从基本概念出发,逐步深入讲解VAE的原理、数学推导和模型架构,帮助读者全面理解这一重要技术。
基本概念介绍
在开始讲解VAE之前,我们需要回顾一些基本概念:
- 先验/后验概率,证据,似然估计,MAP/ML/贝叶斯估计:这些概念是理解VAE的基础,建议参考相关资料进行学习。
- KL散度:用于衡量两个概率分布之间的差异,是VAE中一个重要的数学工具。
从 AutoEncoder 到 VAE
自编码器
自编码器是一种无监督学习的神经网络结构,它试图学习输入数据的紧凑表示(编码),然后通过解码器将该表示还原为输入数据。自编码器包括一个编码器网络和一个解码器网络。
- 编码器:将输入数据映射到低维潜在空间,捕捉输入数据的重要特征。
- 解码器:将编码的潜在表示映射回原始输入空间,重构原始数据。
变分自编码器做出的改变
VAE与自编码器最大的区别在于潜在表示。在自编码器中,潜在表示是一个固定值,而在VAE中,潜在表示是一个概率分布。具体来说:
- 在VAE中,编码器不再只学习提取输入数据的编码信息,而是去学习获取输入数据的概率分布。
- 原始论文中设定这一概率分布为正态分布,模型结构如下图所示:
- 中间量我们不再叫潜在变量,而是称为潜在空间(也称潜在分布,隐变量等),并使用 Z 来表示,用来凸显其是一个变化的量。
- 解码器要做的工作就是如何从这样的概率分布中采样并还原成最终的输出。
VAE 原理思路入门
我们想做什么
生成式模型的“梦想”是根据一批数据样本 {X1, …, Xn} 得到 X 的分布 p(X),进而通过采样生成新的数据。然而,这个“梦想”很难实现,于是我们通过一个迂回的策略,做一个概率分布映射,从一个简单的分布(如高斯分布)映射到 p(X)。
然而,Z 所在的潜在空间通常是高维且包含复杂相互作用的,直接去积分来计算 p(X) 几乎是不可能的,于是乎,我们就需要将这个问题简化、近似化。于是,变分下界(Evidence Lower BOund,ELBO)的概念呼之欲出。
变分下界引入与推导
VAE通过引入变分下界来解决计算 p(X) 的问题。具体推导过程如下:
- 我们可以说,对于 z~P(z) 的大部分采样,也就是大部分 z,对于 P(X) 的计算都没有贡献,也就是它们的 P(z|X) 都近乎为0,根本就跟 X 没什么关系。因此如果需要近似,我们可以从这个角度切入,剔除那些没有什么贡献的 z,只需要计算使得 P(z|X) 更大的那部分 z 即可。
- 怎么找到这部分贡献大的 z 呢?在给定 X 的情况下 z 的后验分布P(z|X) 就约等于使得 X 的生成概率最大的 z 的分布,所以问题就变成了如何计算后验分布 P(z|X)。而直接去计算 z 的后验分布是很困难的。于是我们引入一个新的近似后验分布 q,使其近似代替真实后验分布 P(z|X),式子如下:
- 我们在这里使用KL 散度来将这个近似后验分布同我们要求的联系起来。由 KL 散度公式,我们可以有下式:
- 使用贝叶斯公式转化右式的 p(z|x),式子变形如下:
- p(X) 是确定量,我们将其抽出,并进行移项:
- 再使用 KL 散度公式进行重写,我们就得到了这个式子:
- 由于 KL 散度非负,因此我们可以说:
- 上面式子的 RHS(右式)很明显可以算是 log p(x) 的下界,我们一般称其为变分下界(Variational Lower Bound,ELBO)。实际上,我们的目标和 ELBO 的差距就是近似后验分布 q(z|x) 和真实后验分布 p(z|x) 的差距。至此,我们将 “使 p(x) 最大化” 这一问题转化为了将变分下界最大化。
变分下界的理解
变分下界主要由两部分组成:
- z 在 q(z|x) 的分布下,x given z 的概率分布的期望值
- z given x 的近似后验分布与 z 的真实分布(先验分布)的 KL 散度
- 首先,要想最大化 ELBO,那我们自然是想让第一项尽可能的大,也就是x given z 的概率分布期望值更大。这很明显就是由 z 到 x 重组的过程,也就是 AutoEncoder 中的Decoder,从潜在空间 Z 中重组 x。模型想做的是尽可能准确地重组。
- 其次,要想最大化 ELBO,我们自然需要让这项 KL 散度尽可能小,也就是潜在空间 z 的近似后验分布尽可能接近于 z 的先验分布!这一项我们可以理解为,模型想让 z 尽可能避免过拟合,而让 z 的近似后验分布尽可能接近其先验分布。那如何做到这一效果呢?只能在生成 z 的时候,也就是从Encoder上下手了。
VAE 模型架构介绍
根据潜在空间确定模型架构
理解了核心公式和目标后,我们就可以着手搭建模型了。首先需要确定 z 的表示方式。VAE假设 z 的样本可以从简单的分布中抽取,即标准正态分布 N(0, I),其中 I 是单位矩阵。这是因为任何 d 维度的分布都可以用一组 d 个服从正态分布的变量,通过足够复杂的函数进行映射从而生成。
具体实现时,使用两个神经网络分别输出平均值和标准差:
- 其中 f_1 和 f_2 分别代表两个独立的神经网络
- 选择拟合 log σ^2 是因为原本 σ^2 为非负,需要加激活函数,如果去拟合其 log 值就不用加激活函数了。
这下我们就可以将我们的近似后验分布 q 描述为下面的公式:
- 其中,μ 和 σ^2 就是通过两个不同的神经网络,根据样本学习到的平均值和方差。
- I 为单位矩阵。
模型架构如下:
- 首先,样本进入 Encoder,Encoder 学习并输出潜在空间的平均值和标准差,得到潜在空间 z,
- 然后再从潜在空间中采样,并进入 Decoder,Decoder 根据采样进行重构,重新生成样本。
- 根据我们的目标函数,只需要保证重构尽可能准确 + 潜在空间接近标准正态分布即可,即 ELBO 最大化。那么我们可以直接对 ELBO 进行取反作为我们的损失函数:
对模型架构进行调整
遇到问题我们就去解决问题。我们来看看同为生成模型,GAN(生成式对抗网络)是如何解决的:
- GAN 主要由两部分:生成器和判别器两部分组成。通过一个生成器网络生成样本,同时通过一个判别器网络对生成的样本进行判别。训练时,我们将真样本也给到判别器网络,让其进行训练判别能力。而生成器的训练目标就是能尽可能欺骗过判别器,让它识别不出来自己生成的样本。
- 也就是说,GAN的生成过程是一个对抗性的过程,生成器和判别器相互竞争,最终生成器试图生成逼真的样本,判别器试图准确地区分真实和生成的样本。
VAE 则不是这样粗暴,而是采用了一种精妙的迂回方式。既然直接比较是找不到对应关系的,那我干脆就一对一进行训练,直接一个真实样本训练一个潜在空间,这样重构产生的样本自然就对应着它的老爸啦。修改后的模型示意图如下:
如此改动后,我们就有了专属于每一个 Xk 的正态分布,从中采样并进行重构的自然就是对应的 Zk,如此我们就可以直接进行比较。于是乎,我们的损失函数就可以进一步完善成下式:
- 其中,θ 和 φ 分别是 Decoder 和 Encoder 模型参数
- 我们针对每一个样本都单独计算其独有的均值和标准差,构造属于其专有的潜在空间。
- 我们也重新对我们的近似后验分布进行描述,由于在损失函数中,我们需要其对数形式,所以我们将对数形式添加上去,最终的公式如下:
值得一提的是,有一个很有意思的地方在于损失函数的第二项。我们在之前的变分下界解析中曾经提到,这一项主要目的是为了防止潜在空间过拟合。当知晓了模型架构后,我们重新来看损失函数。第一项很自然的,就是重构项和对应的样本之间的差距,越小越好。然而,在整个模型中,潜在表示,也就是重构材料 Z_k 是采样得到的,并不是像常规 AutoEncoder 那样由 Encoder 直接计算得到,因此这部分也就相当于噪声,它的随机性在干扰重构的过程。因此在训练过程中,为了更好重构,模型会尽可能让潜在空间的方差变为0,进而退化成普通的 AutoEncoder,所谓的“生成式模型”可就名存实亡了。这可万万不能!此时,损失函数的第二项就起到了作用,它让潜在空间的后验分布逼近标准正态分布N(0,I),从而避免了随机性消失,也就是方差变成0的情况,相当于对训练过程的正则化。因此,我们通常称损失函数中:
这一项为重构项(Reconstruction Term),而另外一项:
这一项为正则化项(Regularization Term)。
重参数技巧
在训练过程中,从概率分布中采样得到潜在表示 Z_k 的操作是不可导的,这导致无法进行反向传播。为了解决这个问题,VAE 使用了重参数技巧(reparameterization trick)。具体来说:
- 我们重新观察我们的潜在空间 Z,也就是后验分布 q(z|x),利用正态分布标准化,我们可以得到下面的结论:
- 即,(z − μ) / σ 服从均值为 0,方差为 1 的标准正态分布。因此我们引入噪声项 ε,令 ε = (z − μ) / σ,从而将原本从 N(μ, σ^2) 中采样得到 z的操作转换成了从 N(0, I) 中采样一个 ε,令 z = μ + ε*σ。如此一来,梯度计算可以通过 μ 和 σ 直接传递,而不再涉及对随机采样的梯度。
VAE 模型总结
现在我们整体看一下整个 VAE 的模型结构,实际上它就是从普通的自编码器发展过来的变种。普通的 AutoEncoder,其 Encoder 生成的是有关样本的“信息”,也就是潜在表示,这样算出来的值是确定的。而 VAE 的 Encoder 却生成的是一个潜在空间,更具体地说是生成专属于当前样本的平均值和方差,这样算出来的“值”是不确定的。而从这样的潜在空间采样后再进行重构,这一过程本身就相当于“给潜在表示添加噪声”,相当于对 Encoder 的正则化,这样就使得 Decoder 能够对噪声具有一定的鲁棒性。
从这个角度来看,生成方差的那个神经网络又何尝不可以理解为对噪声大小的调节器呢?方差越大,采样的结果就会越分散,这就变相增加了重构的难度;方差越小,采样的结果就越集中,就会降低重构的难度。引用变分自编码器(一):原来是这么一回事 - 科学空间|Scientific Spaces这篇文章中的内容来说,就是:
当decoder还没有训练好时(重构误差远大于KL loss),就会适当降低噪声(KL loss增加),使得拟合起来容易一些(重构误差开始下降);反之,如果decoder训练得还不错时(重构误差小于KL loss),这时候噪声就会增加(KL loss减少),使得拟合更加困难了(重构误差又开始增加),这时候decoder就要想办法提高它的生成能力了。