PaperWeekly
首发于PaperWeekly

通俗理解变分自编码器VAE(variational auto-encoder)

一、前言

VAE是一种生成式模型,生成模型的分类可以参见下图。生成模型主要对数据的结构进行建模(discover structure of data),捕捉数据不同维度之间的关系,从而可以由模型来生成新的数据。假设我们现在有一个数据集X,生成模型希望产生和这个数据集相同分布的数据。

二、潜变量模型(latent variable model)

我们首先介绍什么是潜变量。顾名思义,潜变量就是观察不到的变量,这是相对于可观测变量而言的,比如说mnist数据集,可观测变量就是28x28维的图像变量。而我们认为,可观测变量是由潜变量产生的。我们记潜变量为z,可观测变量为x。举个例子,mnist数据中出现了一个手写数字7的图像,这个图像为什么会出现呢?我们认为,写这个数字的人首先脑子里想要写一个数字7,而写这个数字7需要什么元素呢?需要一横,一竖,同时这一横和一竖之间需要有一定的角度,这些元素就是所谓的潜变量,这个潜变量确定了,就能写出一个数字7。而我们观测到的只是这个数字7的图像,对应的潜变量则是不知道的。值得一提的是,稍微改变一下这个潜变量,也能得到一个数字7,比如说一横和一竖之间的角度稍微变化一点,对应的也是一个7,只不过和之前的7略有不同。

数据集中每个数据点x都有一个相应的潜变量z,z通过某一个变换f(z,θ)可以得到x。θ是这个变换的参数。这就是所谓的潜变量模型。

一个好的潜变量模型就在于,它的变换f(z,θ)能将潜变量的分布变换为观测数据X的分布。换句话说,它能使观测数据X的似然函数P(X)最大。如果我们能通过优化使得P(X)最大,那么就能得到这个潜变量模型了。这是极大似然法的思想。要想优化P(X),我们首先需要得到它关于z和θ的表达式:

P(X)=\int P(X|z;\theta)P(z)dz (1)

,这个积分的意思就是,比如说X是手写数字7的图像,我们就要把所有能产生7的隐变量z积起来。积分符号里面的第一项对应之前我们所说的变换f,在VAE中, P(X|z;\theta)=N(X|f(z;\theta), \sigma^2*I) ,把 P(X|z;\theta) 表示为均值是f,方差是 \sigma^2 的高斯分布这样一个概率形式的原因是,如果我们直接把 P(X|z;\theta) 表达为f这样一个确定的变换函数形式,就无法在后面通过对 P(X) 求导然后采用梯度下降的方式来优化参数θ(因为从概率的角度看,给定z和θ值,f唯一确定,此时对z积分后P(X)是一个delta冲激函数,他只在某一个x上有响应,这是不可导的,而形如高斯分布这样光滑的倒钟型曲线是可导的)。

三、Variational auto-encoder(VAE)变分自编码器

接下来正式介绍VAE。VAE就是一种潜变量模型。那么问题来了,为了优化(1)式,我们应该1.如何定义z,2.如何处理式子中的积分?

首先我们不可能手工去定义z,因为太复杂了,以mnist为例,z可能是一个m维向量,对应元素分别表示有几个笔画,每个笔画分别是什么,每个笔画之间的角度是多少等等...这样一个m维向量的分布太复杂了,我们不可能人工刻画。我们知道,混合高斯可以拟合任意分布,那么我们就假设输入是一个单位高斯分布P(z)~ N(0,I) ,然后通过神经网络去对这个高斯各个维度做混合,最终在某一层网络上得到我们所说的真正的m维潜变量。然后用后续的神经网络来表示变换函数f,将潜变量变换为x。这一个过程我们称为decoder(将潜变量z解码为x)。

接下来是如何处理(1)式中的积分。(1)式其实就是 P(X|z;\theta)关于z的期望,有人会说那我们从输入的单位高斯分布中采样许多z然后送入神经网络学习潜变量再送入后续网络学习得到x不就行了吗?但如果潜变量维度很高,关于潜变量的积分是很困难的(指数增长),也就是说,我们很难确保我们想要的z的每个值都能被取到(很多z可能并不能被变换为我们所想要的x,例如我们想要数字7,一横一竖加一个角度,如果这个角度是180°,显然不是我们所想要的7),如果真要这么干,我们可能要从p(z)中采样超级多超级多的点才行。这里大家可以想一下,为什么我们一定要取到能变换到x的z呢?这是因为只有从这样的z开始变换,才有可能得到我们想要的x,才能后面进一步通过梯度反传来优化f变换的参数(也即神经网络的参数),如果输入都是不对的,参数再怎么优化也没用。因此直接优化P(X)很难,我们换一个优化目标。

下面就是VAE的关键部分。

既然P(z)这个概率分布里面很多z并不能被变换为我们所想要的x,那么我们能不能换一个分布Q(z),使得这个Q(z)分布中的z被变换为我们所想要的x的可能性比较大,这样我们就能少采样很多点了。

z能变换为x,那么相应的某一个x也能对应一个z,我们记这样的z的条件分布为 P(z|X) ,也就是后验分布。既然我们想要使得Q(z)分布中的z被变换为我们所想要的x的可能性比较大,很明显如果这个Q分布就是 P(z|X) 的话,那再好不过了,因为这时候每个z一定能被变换到x。但是 P(z|X) 很难得到,大家可以想一下为什么很难得到?因为现在我们连变换f的参数都不知道,怎么从x反变换到z呢?所以我们要试着用尽可能简单的分布Q来近似 P(z|X) ,这其实就是变分的思想(variational)。

我们用KL散度来表示Q和 P(z|X) 之间的距离:

(2)可进一步化简:

最终化简到下面的形式:

如果大家对EM算法熟悉,不难发现4式等号右边就是EM中提到的对数似然函数的下限。这时如果在Q中能引入x就好了,因为x是观测变量,是我们已经观测到的,也即 Q(z|X) 。那么4式进一步写成:

等号左边就是我们想要优化的,即使得x的对数似然函数最大,并且使得 Q(z|X) 能和 P(z|X) 尽可能接近。对应的,就等于优化等式右边这个下限(x对数似然函数的下限提高了,似然的本身不就也高了对吧)。然后问题就转为优化等式右边了。

这个就很好优化了,首先看5式等号后面第二项,P(z)是z的先验,也就是前文所说的单位高斯分布,所以是有解析表达式的。 Q(z|X) 我们可以用神经网络来表示,让神经网络自己去拟合Q这个分布。这个网络的输入是X,输出z,与前文的decoder对应,这个网络我们称为encoder(将x编码为潜变量z)。但是问题来了,如果我们很简单的直接输入一个x,网络输出一个z,那我们还是得不到Q的解析表达式(因为计算Q和P(z)的KL距离需要这两个分布的解析表达式都已知),而且,VAE的目的就是为了显式建模潜变量的分布,这就要求我们能得到Q的解析表达式。这时,既然z的先验分布是高斯,我们不妨就假设它的后验也是高斯吧,高斯分布可以用均值和方差两个数表示,那我们就让神经网络输出两个值,一个是均值一个是方差,然后我们通过采样得到z。这样一来,我们就得到了Q的解析表达式,就能计算Q和P(z)的KL距离了。接下来我们来看5式等号后面第一项,z是我们采样得到的,X是观测到的,优化这一项的意思就是我们希望采样得到的z变换到X域后的结果能和我们观测到的X尽可能相近,换句话说就是要让观测到的X和f(z;θ)之间的差尽可能小,我们可以用两者之间的L2距离来表达这个意思。这样一来,5式等号右边我们就可以计算了,神经网络的优化目标就是要使5式等号右边尽可能大。但是还有最后一个问题,我们在encoder中输入x,得到Q的均值和方差后,是通过对这个分布采样得到z的,这个操作的梯度可不能反传啊,不解决这个问题,整个网络就无法训练。VAE的作者用了一个trick,引入一个 \epsilon \sim N(0, 1) ,然后我们从这个分布里采样一个 \epsilon ,让z取值为Q的均值+Q的标准差* \epsilon ,这样就避免了从Q的分布里采样,只要从 \epsilon 的分布中采样就可以了,而 \epsilon 是不需要梯度的,这样使得整个网络的梯度可以反传了。

我们用一张图来表示整个过程(图片来源在水印中。。。):


四、VAE与GAN的对比

VAE相比GAN的优势在于,GAN是implicit density,意思是它对潜变量的分布隐式建模,整个GAN训练完后我们是不知道潜变量具体分布是怎么样的,也就无法随心所欲生成想要的图片,我们只能任意的输入一个噪声,然后网络的生成数据看起来像训练数据集中的数据。但是VAE是explict density,它对潜变量的分布显式建模,我们训练完VAE后是可以得到潜变量的具体分布的,因此也就可以指定生成的数据的样子。

VAE相比GAN的劣势在于,它没有GAN那样的判别器,所以最后生成的数据会比较模糊(以图片数据为例)。当然也有结合VAE和GAN的工作。

编辑于 2019-03-18

文章被以下专栏收录

    PaperWeekly是一个推荐、解读、讨论、报道人工智能前沿论文成果的学术平台。