VAE:变分自动编码器解析

Kingma, Diederik P., and Max Welling. "Auto-encoding variational bayes." arXiv preprint arXiv:1312.6114 (2013).

论文的理论推导见:https://zhuanlan.zhihu.com/p/25401928html

中文翻译为:变分自动编码器git

转自:http://kvfrans.com/variational-autoencoders-explained/github

下面是VAE的直观解释,不须要太多的数学知识。 网络

什么是变分自动编码器?数据结构

为了理解VAE,咱们首先从最简单的网络提及,而后再一步一步添加额外的部分。框架

 

一个描述神经网络的常见方法是近似一些咱们想建模的函数。然而神经网络也能够被看作是携带信息的数据结构。函数

 

假如咱们有一个带有解卷积层的网络,咱们设置输入为值全为1的向量,输出为一张图像。而后,咱们能够训练这个网络去减少重构图像和原始图像的平均平方偏差。那么训练完后,这个图像的信息就被保留在了网络的参数中。性能

 

 

如今,咱们尝试使用更多的图片。此次咱们用one-hot向量而不是全1向量。咱们用[1, 0, 0, 0]表明猫,用[0, 1, 0, 0]表明狗。虽然这要没什么问题,可是咱们最多只能储存4张图片。固然,咱们也能够增长向量的长度和网络的参数,那么咱们能够得到更多的图片。测试

 

可是,这样的向量很稀疏。为了解决这个问题,咱们想使用实数值向量而不是0,1向量。咱们可认为这种实数值向量是原图片的一种编码,这也就引出了编码/解码的概念。举个例子,[3.3, 4.5, 2.1, 9.8]表明猫,[3.4, 2.1, 6.7, 4.2] 表明狗。这个已知的初始向量能够做为咱们的潜在变量。优化

 

若是像我上面同样,随机初始化一些向量去表明图片的编码,这不是一个很好的办法,咱们更但愿计算机能帮咱们自动编码。在autoencoder模型中,咱们加入一个编码器,它能帮咱们把图片编码成向量。而后解码器可以把这些向量恢复成图片。

 

咱们如今得到了一个有点实际用处的网络了。并且咱们如今能训练任意多的图片了。若是咱们把这些图片的编码向量存在来,那之后咱们就能经过这些编码向量来重构咱们的图像。咱们称之为标准自编码器。

 

可是,咱们想建一个产生式模型,而不是一个只是储存图片的网络。如今咱们还不能产生任何未知的东西,由于咱们不能随意产生合理的潜在变量。由于合理的潜在变量都是编码器从原始图片中产生的。

 

这里有个简单的解决办法。咱们能够对编码器添加约束,就是强迫它产生服从单位高斯分布的潜在变量。正式这种约束,把VAE和标准自编码器给区分开来了。

 

如今,产生新的图片也变得容易:咱们只要从单位高斯分布中进行采样,而后把它传给解码器就能够了。

 

事实上,咱们还须要在重构图片的精确度和单位高斯分布的拟合度上进行权衡。

 

咱们可让网络本身去决定这种权衡。对于咱们的损失函数,咱们能够把这两方面进行加和。一方面,是图片的重构偏差,咱们能够用平均平方偏差来度量,另外一方面。咱们能够用KL散度(KL散度介绍)来度量咱们潜在变量的分布和单位高斯分布的差别。

 

 

为了优化KL散度,咱们须要应用一个简单的参数重构技巧:不像标准自编码器那样产生实数值向量,VAE的编码器会产生两个向量:一个是均值向量,一个是标准差向量。

 

 

咱们能够这样来计算KL散度:

# z_mean and z_stddev are two vectors generated by encoder network

latent_loss = 0.5 * tf.reduce_sum(tf.square(z_mean) + tf.square(z_stddev) - tf.log(tf.square(z_stddev)) - 1,1)

 

当咱们计算解码器的loss时,咱们就能够从标准差向量中采样,而后加到咱们的均值向量上,就获得了编码去须要的潜在变量。

 

 

VAE除了能让咱们可以本身产生随机的潜在变量,这种约束也能提升网络的产生图片的能力。

 

为了更加形象,咱们能够认为潜在变量是一种数据的转换。

 

咱们假设咱们有一堆实数在区间[0, 10]上,每一个实数对应一个物体名字。好比,5.43对应着苹果,5.44对应着香蕉。当有我的给你个5.43,你就知道这是表明着苹果。咱们能用这种方法够编码无穷多的物体,由于[0, 10]之间的实数有无穷多个。

 

可是,若是某人给你一个实数的时候实际上是加了高斯噪声的呢?好比你接受到了5.43,原始的数值多是 [4.4 ~ 6.4]之间的任意一个数,真实值多是5.44(香蕉)。

 

若是给的方差越大,那么这个平均值向量所携带的可用信息就越少。

 

如今,咱们能够把这种逻辑用在编码器和解码器上。编码越有效,那么标准差向量就越能趋近于标准高斯分布的单位标准差。

 

这种约束迫使编码器更加高效,并可以产生信息丰富的潜在变量。这也提升了产生图片的性能。并且咱们的潜变量不只能够随机产生,也能从未通过训练的图片输入编码器后产生。

 

VAE的效果:

我作了一些小实验来测试VAE在MNIST手写数字数据集上的表现:

 

这里有一些使用VAE好处,就是咱们能够经过编码解码的步骤,直接比较重建图片和原始图片的差别,可是GAN作不到。

 

另外,VAE的一个劣势就是没有使用对抗网络,因此会更趋向于产生模糊的图片。

 

这里也有一些结合VAE和GAN的工做:使用基本的VAE框架,可是用对抗网络去训练解码器。更多细节参考:https://arxiv.org/pdf/1512.09300.pdf 和http://blog.otoro.net/2016/04/01/generating-large-images-from-latent-vectors/

 

你能够从这里得到一些这篇博客的代码:https://github.com/kvfrans/variational-autoencoder 和一个整理好的版本: https://jmetzen.github.io/2015-11-27/vae.html