1.2.4 变分自编码器
自编码器(autoencoder)在深度学习中占有重要地位,它最开始只是用于降维或者特征学习。一般的自编码器由编码器(encoder)和解码器(decoder)两个神经网络构成,如图1-11所示。
图1-11 自编码器结构
样本x经过编码器得到它的某种编码表示z,而且z的维度一般小于x,再将编码向量z送入解码器则可得到样本x的重构x′。如果重构的效果比较好,则认为编码器成功地学到了样本的抽象特征,也可以理解为实现了降维。当学习到数据的抽象特征z后,我们不仅可以用于样本的重构,也可以把提取到的抽象特征用于分类问题,只需要在编码器后接一个分类器即可,如图1-12所示。隐变量在生成模型中具有非常重要且广泛的应用,一方面它可以对样本进行某种“有意义”的表示;另一方面,基于隐变量的模型相对于FVBN模型具有更高的采样速度。因为FVBN模型中只包含观察变量,且观察变量被建立前后依赖关系,所以我们可以将其中的部分观察变量修改为隐变量(隐变量是指不可观测到的变量,但它与模型中可观察变量存在某种相关关系),并建立两者的条件概率关系,从而获得更快的采样速度。
图1-12 将自编码器用于分类任务
VAE[7]将自编码器构建成一个生成模型。它将z视为生成样本的隐变量,并对编码器和解码器进行了一些修改,最终实现了一个性能卓越的生成模型。与FVBN和GAN等生成模型不同,VAE希望定义一个通过隐变量来生成样本的生成模型:
这个生成模型生成样本的方式十分简洁优雅:先从隐变量的分布pθ(z)中采样得到z,然后在条件分布pθ(x|z)中采样即可生成样本,但是这个生成模型无法被直接搭建出来!因为训练生成模型通常需要将对数似然函数极大化来求解模型参数θ,即对N个独立同分布的训练样本{x(1),x(2),…,x(N)}来说,要求:。这里必然要计算pθ(x),分析pθ(x)的计算式子。积分号内部是相对容易求解的,对于隐变量z的先验分布pθ(z),可以将其设计为简单的高斯分布,对于pθ(x|z),可使用一个神经网络来学习,难以解决的地方是求积分时需要遍历所有的隐变量z,因为z在理论上是不可能被精确地遍历的。另外,隐变量z的后验分布为:
它也是难以求解的。训练生成模型必须先求解对数似然函数(也就是说以似然函数作为损失函数),然后使其最大。VAE的想法是:虽然无法求解准确的对数似然函数,但可以设法得到对数似然函数的下界,然后令其下界极大化,这就相当于近似地令对数似然函数达到极大。具体做法是,VAE引入一个新的概率分布qφ(z|x)来逼近后验分布pθ(z|x),这时的对数似然函数为:
最终的式子由三项组成,前两项是可以计算的,第三项无法计算,但是根据KL散度的性质可知第三项必定大于或等于0,也就是说
我们将上述不等式右侧称为一个变分下界(ELBO),记为l(x(i);θ,φ),这时只需要最大化变分下界即可,即将变分下界作为模型的损失函数:
至此,VAE的最核心的想法已实现,接下来将描述一些细节,例如,如何将数学模型转换到神经网络上?即如何计算变分下界 EBLO?首先来看 EBLO的第二项DKL(qφ(z|x(i))pθ(z)),计算隐变量z的后验分布的近似分布qφ(z|x(i))和隐变量的先验分布pθ(z)的KL散度。基于实际经验,我们做出两个基本假设:①隐变量的先验分布pθ(z)为D维标准高斯分布N(0,I),注意这时的pθ(z)将不包含任何未知参数,重新记为p(z);②隐变量的后验分布的近似分布qφ(z|x(i))为各分量彼此独立的高斯分布N(μ,Σ;x(i)),也就是说,每一个样本x(i)均对应一个D维高斯分布N(μ,Σ;x(i))。现在只需要再知道μ(x(i))、Σ(x(i))就可以计算KL散度了。我们用两个神经网络(即编码器,参数为φ)来求解均值、方差的对数(因为方差的对数的值域为全体实数,而方差的值域为全体正实数,使用神经网络拟合方差的对数不需要精确限定激活函数,相对方便)。由于D维隐变量z的每个维度彼此独立,则均值为D维向量,而方差为D维对角矩阵,即
此时,方差其实也只有D个需要学习的参数,而不是D2个。那么这里的编码器的输入为样本x(i),第一个编码器输出D维向量[μ1,μ2,…,μD],第二个编码器的输出也为D维向量[],即
由于两个高斯分布的每个维度彼此独立,KL散度可分开计算,其中第d维的KL散度值为:
上述计算过程比较简单,在此不展开。易知总KL散度为:
在计算上,通过让编码器学习隐变量后验分布的近似分布的均值和方差,我们得到了隐变量后验分布的近似分布的概率密度表达式,从而可以计算 KL散度。本质上,VAE训练编码器是希望KL散度值达到最小,即令后验近似分布趋近于标准高斯分布,也就是说,对每个样本x(i),qφ(z|x(i))都向高斯分布靠拢。
现在来看ELBO的第一项 Ez[logpθ(x(i)|z)]。为了计算这一项,我们需要使用一个经验上的近似:
计算这一项时并不需要采样所有不同z再计算logpθ(x(i)|z),而只需要从中采样一次即可。这样的做法看似不合理,但实际效果证明约等于的关系是成立的,另外,联想到一般的自编码器中是一一映射的,即一个样本x对应一个隐变量z,可认为qφ(z|x(i))是一个非常锐利的单峰分布,故多次采样计算均值和一次采样效果相差不大。接下来,为了计算logpθ(x(i)|z),我们再次做出假设,假设pθ(x|z)是伯努利分布或高斯分布。当假设为伯努利分布时,对应的x为二值(0 1)、Q个维度彼此独立的向量,将伯努利分布的Q个参数[ρ1,ρ2,…,ρQ]交给神经网络学习,这个神经网络即解码器,它由θ来参数化,其输入为隐变量z,输出为[ρ1,ρ2,…,ρQ],即
现在可以计算样本的似然为:
相应的对数似然函数为:
所以只需要把编码器的最后一层激活函数设计为sigmoid函数,并使用二分类交叉熵作为解码器的损失函数即可。若假设pθ(x(i)|z)为高斯分布,对应的x为实值、Q个维度彼此独立的向量,将该高斯分布每个维度的方差固定为某个常数σ2,而Q个均值参数[μ1,μ2,…,μQ]交给神经网络学习,这个神经网络即解码器,它同样由θ来参数化,输入为隐变量z,输出为[μ1,μ2,…,μQ],即
现在可以计算样本的似然函数为:
相应的对数似然为:
所以需要把编码器的最后一层激活函数设计为值域为全体实值的激活函数,并使MSE作为损失函数。在计算上,我们基于经验知识使用了一次采样的近似操作,并依靠编码器学习pθ(x|z)的参数,最后计算条件概率下样本的似然。VAE希望将解码器部分对应的损失函数的值最大,本质上是希望样本的重构误差最小,这在伯努利分布中非常明显,而在高斯分布中,MSE损失希望编码器的输出(高斯分布的均值)与样本尽可能接近。
回顾上面的过程,训练流程是这样的:将样本x(i)送入解码器可计算得到隐变量后验近似分布的各项参数(即高斯分布的均值和方差),这时需要从分布中采样一个隐变量z,然后将z送入解码器,最后计算损失函数,并反向传播更新参数。其实这里有一个小问题,从分布中采样的过程是不可导的,即编码器计算的均值和方差参数在采样得到隐变量后就被“淹没”了,解码器面对的只是一个孤立的、不知从哪个高斯分布采样得到的z。我们需要把μ(x(i))、σ(x(i))与编码器建立计算上的联系,否则反向传播时,梯度传播到采样得到z的环节就会中断。重参数技巧(Reparameterization Trick)做了一个简单的处理,它直接在标准正态分布中采样N(0,I)得到ε,然后令z=μ+ε×σ,这样,反向传播的环节被打通,如图1-13所示。
图1-13 变分自编码器正向计算
训练完成后,直接从p(z)中采样得到隐变量z,然后送入解码器,在伯努利分布中解码器输出样本每个维度取值的概率;在高斯分布中解码器输出均值,即生成的样本。
VAE与GAN经常被用来进行比较,GAN属于隐式概率生成模型,在GAN中没有显式出现过似然函数,而VAE属于显式概率生成模型,它也试图最大化似然函数,但是不像FVBN模型中存在精确的似然函数以供其最大化,而是得到了似然函数的下界,近似地实现了极大似然。在图像生成问题上,VAE的一个比较明显的缺点是,生成图像模糊,这可能是使用极大似然的模型的共同问题,因为极大似然的本质是最小化DKL (pdata||pmodel),这个问题的解释涉及KL散度的性质,在此不再展开。
VAE模型的核心代码如下: