9  第九章

9.1 自动编码器

自动编码器是基于编码器-解码器结构的模型,它实际上是在试图寻找当前数据很好的低维度表征,或者逼迫网络学会“提炼核心”,其中编码器用于压缩输入数据,解码器用于重构原始数据:

图 9.1: 自动编码器

图 9.1 所示,编码器将输入数据压缩成一个低维数据\(z\)\(z\)通常被称为潜变量或潜在变量,解码器再根据输入的潜变量试图最大程度地恢复原始数据。

因此对于训练集\(x_1,\dots,x_N\),其损失函数为: \[ \text{loss}=\frac{1}{N}\sum_{i=1}^N \|x_i - g_\phi(f_\theta(x_i))\|^2 \tag{9.1}\]

那为什么要得到一个潜变量\(z\)呢?我们可以把解码器看成是一个单独的生成模型,潜变量则只需要描述最基本的信息让计算量大幅减少。同时维度的减小能让模型学会抓住描述数据最本质的信息,抛弃所有不重要的冗余噪点,只提炼出最核心的骨架。

以mnist数据集为例,原始数据是一个28*28的图像,内容是0~9的手写数字:

图 9.2: MNIST数据集样例

把图片展开成一列,成为一个784维的向量,用MLP组成编码器和解码器,其编码器维度为从784到中间层的256,再到64,再到12,最后选择潜变量维度为3。解码器则反过来,采用 式 9.1 的损失函数,经过训练后损失从初始约0.5降低到0.0336。

首先可以注意到从784维到3维压缩比达到了\(\frac{3}{784}\approx 0.0038\),在这样压缩比的基础上,解码器居然能恢复出不错的图片:

图 9.3: 输入与输出对比

虽然也会观察到,重构出来的数字边缘被模糊掉了,可能的原因有很多,比如潜变量维度太低,均方损失天然地有平均模糊的倾向等等。

但最重要的是,我们真的可以用三维数据表示28*28的手写数字灰度图,这是件很厉害的事情。而潜变量之所以选择三维,是为了可视化方便,对于不同的图片输入,可视化它们的潜变量:

图 9.4: 自编码器在三维潜在空间中的数据分布

可以看到相同数字图片的潜变量在空间里呈现出了一定的聚类,特别是红色的数字3看起来会更集中一些,毫无疑问网络学到了关于数字3的更基本的特征。

理想情况下,我们可以把解码器单独拿出来,输入三维潜变量生成图片,但这只对训练样本生成的潜变量适用。因为目前的潜空间充满了“空洞”,簇群之间存在大片空白的“无人区”,从这些空白区域解码出来的图片通常是一团不可名状的东西。

另一个原因是潜变量分布不规则和尺度失衡。在 图 9.4 中可以只显示数字0的潜变量,然后可以看到它的一个维度跨度从-20到了-70。这毫无规律可言,若想单独生成潜变量,没法判断是要选择-20、-70或者中间的某个数字。

图 9.5: 随机潜变量生成的图片

9.2 变分自动编码器

为了解决空洞和尺度失衡的问题,变分自动编码器(VAE)尝试把潜空间看成是一个概率分布空间,而不是离散点的聚集空间。

9.2.1 联合分布

联合分布描述了两个或多个随机变量同时取特定值时的概率分布。例如二维随机变量 \((x, z)\) 的联合分布 \(Pr(x, z)\) 可以直观地用三维曲面来表示,如 图 9.6 所示。如果沿着其中一个变量的方向对曲面进行积分,就能分别得到单个变量的边缘概率分布:

\[Pr(x) = \int Pr(x, z) dz\] \[Pr(z) = \int Pr(x, z) dx\]

图 9.6: 连续二维联合概率分布及其边缘分布

考虑计算联合分布下的条件概率分布\(Pr(x|z)\)\(Pr(z|x)\),计算方法可以理解为给定条件下的切片和归一化:

\[ Pr(z|x)=\frac{Pr(x,z)}{Pr(x)}=\frac{Pr(x,z)}{\int Pr(x,z)dz} \] \[ Pr(x|z)=\frac{Pr(x,z)}{Pr(z)}=\frac{Pr(x,z)}{\int Pr(x,z)dx} \]

9.2.2 视角切换

VAE假设潜变量\(z\)在潜空间里满足正态分布 \(\mathcal{N}(0, I)\),解码器用于计算条件概率分布\(Pr_\phi (x|z)\),假定它也满足正态分布,其中\(\phi\)是解码器参数,输出的是给定\(z\)的情况下关于\(x\)的均值\(\mu_\phi (z)\),因此\(Pr_\phi (x|z) \sim \mathcal{N}(\mu_\phi (z),I)\)

为了优化参数 \(\phi\),我们希望各个训练样本 \(x_i\) 处的似然度\(Pr_\phi(x_i)\) 越大越好,即:

\[ \hat{\phi} = \arg \max_\phi \prod_{i=1}^N Pr_\phi(x_i) \]

根据联合概率,公式等价于在最小化负对数似然:

\[ \begin{aligned} &-\sum_{i=1}^N \log \left(\int Pr_\phi (x_i|z)Pr(z)dz\right) \\ = &-\sum_{i=1}^N \log \left(\int Pr_\phi (x_i,z)dz\right) \end{aligned} \]

但这个积分是无法计算的,因为解码器 \(Pr_\phi(x_i|z)\) 是一个神经网络,数学上无法求出解析解。

为此引入编码器 \(q_\theta (z|x)\),编码器在给定具体样本 \(x_i\) 的情况下计算 \(z\) 的条件概率分布,输出 \(\mu(x_i)\)\(\sigma(x_i)\)(希望这个概率分布与标准正态分布接近),积分可以改写为:

\[ \int Pr_\phi (x_i|z)Pr(z)dz = \int q_\theta (z|x_i) \frac{Pr_\phi (x_i|z)Pr(z)}{q_\theta (z|x_i)}dz \]

而后者可以表示为 \(\frac{Pr_\phi (x_i|z)Pr(z)}{q_\theta (z|x_i)}\) 的期望(均值)。利用Jensen不等式将对数函数移入期望内部转化为其上界,最后损失函数可以表示为:

\[ \mathcal{L}(\theta, \phi) = \sum_{i=1}^N \left( \underbrace{-\mathbb{E}_{z \sim q_\theta(z|x_i)}\left[ \log Pr_\phi(x_i|z) \right]}_{\text{重构损失}} + \underbrace{D_{\text{KL}}\left( q_\theta(z|x_i) \parallel Pr(z) \right)}_{\text{KL 散度正则项}} \right) \]

其中重构损失(表达式与假设解码器输出分布有关)在于尽量让输出图片与原始图片尽可能相似,它趋向于让潜变量像自动编码器那样“粒粒分明”,KL散度正则项(表达式与假设编码器输出分布与潜变量分布有关)则强调让编码器的输出尽可能接近标准高斯分布,用于消除潜空间的空洞,可以说它们俩是“相互抵抗”的关系,想要图片越逼真,潜变量就会越自由,想要潜空间没有空洞,潜变量就会聚在一起。

9.2.3 MNIST测试

为了直观验证这种“相互抵抗”的机制,我们依然以 MNIST 数据集为例,保持与前面自编码器相同的网络结构,引入权重系数 \(\alpha\)\(\beta\) 来调节两项损失的比重:

\[ \text{loss} = \alpha \cdot \text{重构损失} + \beta \cdot \text{KL散度正则项} \]

分别训练三种不同配置下的模型,并在三维潜在空间中可视化测试集样本的潜变量分布,如下图所示:

图 9.7: 三维潜空间中重构损失与KL散度对潜空间影响对比

图 9.7 的三种潜空间分布对比中,我们可以清晰地看到这两种力量的博弈:

  • 仅重构损失(\(\alpha=1, \beta=0\)):模型等价于普通的自编码器。编码器只顾着重构准确,不同类别的数字虽然能聚类得很好,但簇群之间存在极其空旷的“无人区”,如果从空白处随机采样潜变量,解码器根本无法生成合理的数字。
  • 仅 KL 散度(\(\alpha=0, \beta=1\)):模型完全丢弃了图片重构任务,只惩罚与标准正态分布的偏离。导致编码器彻底“摆烂”,所有潜变量全部挤压在一起,模型失去表现能力。
  • 完整 VAE(\(\alpha=1, \beta=1\)):两者达到了平衡。KL散度让潜空间变得比较紧凑,重构损失又能保证模型能力。