变分自编码器解析

Posted weilonghu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了变分自编码器解析相关的知识,希望对你有一定的参考价值。

概述

译自https://jaan.io/what-is-variational-autoencoder-vae-tutorial/

在讨论变分自动编码器时,为什么深度学习研究人员和概率机器学习人员会感到困惑? 什么是变体自动编码器? 为什么这个词会引起混乱?

这是因为神经网络和概率模型在基本概念和描述语言上存在差异。此教程的目标是弥合这一思想鸿沟,允许在这些领域之间进行更多的协作和讨论,并提供一致的实现方法。

变分自编码器用起来很酷,让我们能够设计复杂的数据生成模型,并将其应用于大型数据集。它可以生成虚构的名人面孔或者高分辨率的数字艺术品图像。这些模型在图像生成和强化学习中获得了非常好的效果。

技术图片

下面本文将从神经网络和概率模型两个角度对其进行讲解。

神经网络角度

以神经网络语言描述的话,VAE包含编码器、解码器和损失函数三部分。编码器将数据压缩到隐空间((z))中。 解码器根据隐状态(z)重建数据。

技术图片

编码器是一个神经网络,它的输入是数据点(x),输出是隐状态(z),它的参数( heta)包括权重和偏置。为了更具体地说明,假设(x)是一副(28 imes 28)的手写数字图片,通常被重塑成784维的向量。编码器需要将728维的数据(x)编码到隐空间(z),而且(z)的维度要比784小很多。这通常被称为“瓶颈”,因为编码器必须学习将数据有效压缩到此低维空间的方法。假设编码器表示为(q_{ heta}(z|x)),我们注意到较低维的隐空间是随机的:编码器将参数输出到(q_{ heta}(z|x)),这是高斯概率密度,然后我们可以从该分布中采样以获得(z)的噪声值。

解码器也是一个神经网络,它的输入是隐状态(z),输出是数据的概率分布,它的参数(phi)也包括权重和偏置,可以把解码器表示为(p_{phi}(x|z))。还是以上面例子讲解,假设每个像素取值是0或者1,一个像素的概率分布可以用伯努利分布表示。因此解码器输入(z)之后,输出784个伯努利参数,每个表示图中的一个像素是取0还是取1。原始784维图像(x)的信息是无法获取的,因为解码器只能看到压缩的隐状态(z)。这意味着存在信息丢失问题。

变分自编码器的损失函数是带正则项的负对数似然函数。因为所有数据点之间没有共享表示,因此每个数据点的损失(l_i)是独立的,总损失(mathcal{L}=sum_{i=1}^N l_i)是每个数据点损失之和。而数据点(x_i)的损失(l_i)可以表示为:

[l_i( heta,phi)=-mathbb{E}_{z sim p_{ heta}(z|x_i)}[log_{p_{phi}}(x_i|z)] + KL(p_{ heta}(z|x_i)||p(z)) ]

第一项是重构损失,或者说是数据点(x_i)负对数似然的期望。第二项KL散度是正则项,它衡量了分布(p)(q)的近似程度,也就是用(q)表示(p)时有多少信息丢失了。

在变分自编码器中,(p(z))被指定为标准正态分布,也就是(p(z)= ext{Normal}(0,1))。如果编码器输出的(z)不服从标准正态分布,将会在损失函数中对编码器施加惩罚。正则化用来保持每个手写数字的隐状态(z)充分多样但又具有意义。如果不使用的话,编码器可能简单地将每个数据点映射到欧几里德空间的不同区域,这会出现问题。比如有两个包含数字2的手写图片(2_{a})(2_b),它们可能会编码成非常不同的隐状态(z_a)(z_b)。而我们希望在隐空间中相同数字的隐状态应该是彼此靠近的,因此需要用正则项进行约束。

概率模型角度

现在,让我们忘掉所有深度学习和神经网络知识,从概率模型的角度重新看变分自编码器。在最后,我们仍然会回到神经网络。

在概率模型框架下,变分自编码器中数据点(x)和隐变量(z)的联合概率表示为(p(x,z)=p(x|z)p(z))。此时,对于每个数据点(i),生成过程可以表示如下:

  • 采样隐变量(z_i sim p(z))
  • 采样数据点(x_i sim p(x|z))

这可以用概率图模型表示;

技术图片

这就是我们从概率模型角度讨论变分自编码器时的核心问题。隐状态(z)从先验分布(p(z))中采样得到,然后数据点(x)从以(z)为条件的分布(p(x|z))中产生。整个模型定义了数据和隐状态的联合分布(p(x,z)=p(x|z)p(z)),对于手写数字而言,(p(x|z))就是伯努利分布。

现在,我们可以考虑如何根据给定的观测数据推断出隐变量,或者说计算后验概率(p(z|x))。根据贝叶斯定理:

[p(z|x)=frac{p(x|z)p(z)}{p(x)} ]

考虑分母(p(x)),它可以通过(p(x)=int p(x|z)p(z)dz)计算。不幸的是,该积分需要指数时间来计算,因为需要对所有隐变量进行计算。 因此,我们需要近似该后验分布。

变分推断使用分布族(q_{lambda}(z|x))来近似后验分布,参数(lambda)指示具体分布族。比如,如果(q)是高斯分布的话,(lambda)就是每个数据点隐状态的均值和方差(lambda_{x_i}=(mu_{x_i},sigma_{x_i}^2))

那么怎么知道用分布(q(z|x))近似真实的后分布(p(z|x))到底好不好呢?我们可以用KL散度来衡量:

[KLleft(q_{lambda}(z|x)||p(z|x) ight) = mathbb{E}_q[log q_{lambda}(z|x)] - mathbb{E}_q[log p(x,z)] + log p(x) ]

我们的目标是找到使得KL散度最小的变分参数(lambda)。最优的后验分布就可以表示为:

[q_{lambda^*}(z|x)=argmin_{lambda}KLleft(q_{lambda}(z|x)||p(z|x) ight) ]

但是这依然无法进行计算,因为仍然会涉及到(p(x)),我们还需要继续改进。引入下面这个函数:

[ELBO(lambda)= mathbb{E}_q[log p(x,z)] - mathbb{E}_q[log q_{lambda}(z|x)] ]

我们可以将ELBO与上面的KL散度计算公式结合,可以得到:

[log p(x)= ELBO(lambda) + KLleft(q_{lambda}(z|x)||p(z|x) ight) ]

由于KL散度始终是大于等于0的,这意味着最小化KL散度等价于最大化ELBO。ELBO(Evidence Lower BOund)让我们能够对后验分布进行近似推断,可以从最小化KL散度中解脱出来,转而最大化ELBO。而后者在计算上是比较方便的。

在变分自编码器模型中,每个数据点的隐状态(z)是独立的,因此ELBO可以被分解成所有数据点对应项之和。这使得我们可以用随机梯度下降来更新共享参数(lambda)。每个数据点的ELBO表示如下:

[ELBO_i(lambda)=mathbb{E}q_{lambda}(z|x_i)[log p(x_i|z)] - KL(q_{lambda}(z|x_i)||p(z)) ]

现在可以再用神经网络来进行描述了。我们使用一个推断网络(或编码器)近似后验(q_{ heta}(z|x,lambda)),该推断网络输入数据(x)然而输出参数(lambda)。再使用一个生成网络(或解码器)参数化(p(x|z)),该生成网络输入隐状态和参数,输出数据分布(p_{phi}(x|z))( heta)(phi)是推断网络和生成网络的参数。此时我们可以使用这两个网络来重写ELBO:

[ELBO_i( heta,phi)=mathbb{E}q_{ heta}(z|x_i)[log p_{phi}(x_i|z)] - KL(q_{ heta}(z|x_i)||p(z)) ]

可以看到,(ELBO_i( heta,phi))和我们之前从神经网络角度提到的损失函数就差一个符号,即(ELBO_i( heta,phi)=-l_i( heta,phi))。我们仍然可以将KL散度看作正则项,将期望看作重构损失。但是概率模型清楚解释了这些项的意义,即最小化近似后验分布(q_{lambda}(z|x))和模型后验分布(p(z|x))之间的KL散度。

模型参数呢?我们忽略了这一点,但这很重要。术语“变分推断”通常是指相对于参数(lambda)最大化ELBO。我们还可以相对于模型参数(phi)最大化ELBO。这项技术称为变分EM(期望最大化),因为我们正在相对于模型参数最大化数据的期望对数似然。

这就是全部了,我们遵循了变分推断的方法,定义了:

  • 概率模型(p)表示隐变量和数据的分布
  • 隐状态的变分分布族(q),用于近似后验分布

然后我们利用变分推断算法学习变分参数(在ELBO上用梯度上升学习(lambda)),利用变分EM算法学习模型参数(在ELBO上用梯度上升学习(phi))。

实验

现在可以模型进行一些实验了,两种方式衡量实验进度:从先验分布或后验分布采样。为了更好地解释学习到的潜在空间,我们可以可视化隐变量的后验分布(q_{lambda}(z|x))

可以参考作者给出的代码:https://github.com/altosaar/variational-autoencoder。

Mean-field推断和amortized推断

这个问题对我来说非常令人困惑,对于来自深度学习背景的人来说,它可能会更加令人困惑。在深度学习中,我们考虑输入和输出,编码器和解码器以及损失函数。在学习概率建模时,这可能导致模糊,不精确的概念。

让我们讨论Mean-field推断和amortized推断的不同之处。这是我们在进行近似推断以估计隐变量的后验分布时所面临的选择。这可能涉及到各种问题:我们是否有大量数据?我们有大量计算资源吗?每个数据点的隐变量是局部独立的,还是全局共享的?

Mean-field变分推断是指在没有共享参数的情况下对(N)个数据点进行分布推断:

[q(z)=prod_i^N q(z_i;lambda_i) ]

这意味着每个数据点都有自由参数(lambda_i)(例如对于高斯隐变量,(lambda_i =(mu_i,sigma_i)))。对于新数据点,我们需要针对其mean-field参数(lambda_i)最大化ELBO。

amortized推断是指“摊销”数据点之间的推断成本。一种方法是在数据点之间共享(摊销)变分参数(lambda)。例如,在变分自动编码器中,推断网络的参数( heta),这些全局参数在所有数据点之间共享。如果我们看到一个新的数据点并想看一下它的近似后验(q(z_i)),我们可以再次运行变分推断(最大化ELBO直到收敛),或者直接使用共享参数。 与Mean-field变分推断相比,这可能是一个优势。

哪一个更灵活呢?Mean-field变分推断严格来说更具表达性,因为它没有共享参数。每个数据点独立的参数(lambda_i)可以确保近似后验最准确。但另一方面,通过在数据点之间共享参数可以限制分布族的容量或表示能力(例如,使用在数据之间共享权重和偏差的神经网络)。

重参数化技巧

实现变分自编码器的最后一件事是如何对随机变量的参数求导数。如果给定从分布(q_{ heta}(z|x))中得出的(z),并且我们想要对( heta)(z)函数的导数呢?此时采样不可导,进而导致模型无法反向传播。

对于某些分布,可以以巧妙的方式重新设置样本的参数,也就是重参数化。例如,在均值(mu)和标准偏差(sigma)的正态分布变量中,我们可以像这样从中采样:

[z = mu + sigma odot epsilon ]

其中(epsilon sim Normal(0,1))。首先从从均值为0,标准差为1的高斯分布中采样,再放缩平移得到(z)。这样从(epsilon)(z)只涉及了线性操作(平移缩放),采样操作在神经网络计算图之外。

技术图片

这张图表示了重参数化的形式,其中圆是随机节点,菱形是确定性节点。

由于水平有限,文中难免出现部分错误,还望交流指出!

技术图片

以上是关于变分自编码器解析的主要内容,如果未能解决你的问题,请参考以下文章

VAE 变分自编码器

VAE 变分自编码器

机器学习-白板推导系列(三十二)-变分自编码器(VAE,Variational AutoEncoder)

一文搞懂变分自编码器(VAE, CVAE)

变分自编码器如何淘汰经典的推荐系统

pytorch 笔记:VAE 变分自编码器