变分自编码器(VAE)算法详解

变分自编码器(VAE)算法详解

VAE模型简明指导

VAE最想解决的问题是如何构造编码器和解码器,使得图片能够编码成易于表示的形态,并且这一形态能够尽可能无损地解码回原真实图像。

这似乎听起来与PCA(主成分分析)有些相似,而PCA本身是用来做矩阵降维的。

如图 5-1 所示, \(\boldsymbol{x}\) 本身是一个矩阵, 通过一个变换 \(\boldsymbol{W}\) 变成了一个低维矩阵 \(\boldsymbol{c}\), 因为这一过程是线性的, 所以再通过一个变换就能还原出一个矩阵, 现在要找到一种变换 \(\boldsymbol{W}\), 使得矩阵 \(\boldsymbol{x}\) 与 \(\hat{\boldsymbol{x}}\) 能够尽可能地一致, 这就是 PCA 做的事情。在 PCA 中找这个变换 \(\boldsymbol{W}\) 用到的方法是奇异值分解 (Singular Value Decomposition, SVD) 算法, 这是一个纯数学方法, 不再细述, 而在 VAE 中不再需要使用 SVD, 直接用神经网络代替。

PCA 与我们想要构造的自编码器的相似之处是: 如果把矩阵 \(\boldsymbol{x}\) 视作输入图像, \(\boldsymbol{W}\) 视作一个编码器, 低维矩阵 \(\boldsymbol{c}\) 视作图像的编码, \(\boldsymbol{W}^{\mathrm{T}}\) 和 \(\hat{\boldsymbol{x}}\) 分别视作解码器和生成图像, PCA 就变成了一个自编码器网络模型的雏形。用两个分别被称为编码器和解码器的神经网络代替 \(\boldsymbol{W}\)变换和 \(\boldsymbol{W}^{\mathrm{T}}\) 变换, 就得到了自编码器模型, 如图 5-1 所示。

图片[1]-变分自编码器(VAE)算法详解-点头深度学习网站

这一替换的明显好处是,引入了神经网络强大的拟合能力,使得编码的维度能够比原始图像的维度低非常多。至此通过自编码器(Auto-Encoder,AE)构造出了一个比PCA更加清晰的自编码器模型,但这并不是真正意义上的生成模型。对于一个特定的生成模型,它一般应该满足以下两点:

(1)编码器和解码器是可以独立拆分的(类比GAN的Generator和Discriminator);

(2)固定维度下任意采样出来的编码,都应该能通过解码器产生一张清晰且真实的图片。

解释下第二点。用一张全月图和一张半月图去训练一个AE,经过训练,模型能够很好地还原出这两张图片,如图5-2所示。接下来在潜空间中取两张图片编码点中任意一点,将这点交给解码器进行解码,直觉上会得到一张介于全月图和半月图之间的图片(如阴影面积覆盖3/4)。然而,实际上,这个点经过解码器解码后的结果不仅模糊而且还是乱码的,这就是自编码的过拟合现象。

图片[2]-变分自编码器(VAE)算法详解-点头深度学习网站

为什么会出现这种现象?一个直观上的解释是AE的Encoder和Decoder都使用了神经网络,神经网络是一个非线性的变换过程,因此在潜空间中点与点之间关系往往没有规律可循。解决此问题的一种方法是引入噪声,使得图片的编码区域得到扩大,从而掩盖掉失真的空白编码点。

图片[3]-变分自编码器(VAE)算法详解-点头深度学习网站

在对两张图片进行编码时引入一定的噪声,使得每个图片的编码点出现在潜空间的矩形阴影范围内,如图5-3所示。因此,在训练模型时,矩形阴影范围内的点都有可能被采样到,这样解码器在训练过程中会尽可能地将矩形阴影内的点还原为与原图相似的图片。接着,对之前提到的失真点,此时它位于全月图和半月图编码的交界处。因此,解码器希望失真点既能尽量与全月图相似,又能尽量与半月图相似,因此它的还原结果将是两种图的折中(例如3/4的全月图)。通过这个例子发现给编码器增加一些噪声,可以有效覆盖失真区域。

然而,引入区域噪声的方法还不够充分,因为噪声的范围总是有限的,不可能覆盖所有采样点。为了解决此问题,可以尝试将噪声的范围无限延伸,以使得对于每个样本,其编码能够覆盖整个编码空间。但是需要确保,在原始编码附近的编码点具有最高的概率,随着离原始编码点的距离增加,编码的概率逐渐减小。在这种情况下,图像的编码将从原来离散的编码点变成一个连续的编码分布曲线,如图5-4所示。

图片[4]-变分自编码器(VAE)算法详解-点头深度学习网站

这种将图像编码由离散变为连续的方法,就是变分自编码的核心思想。接下来介绍VAE的模型架构,及VAE如何实现上述构思。

图片[5]-变分自编码器(VAE)算法详解-点头深度学习网站

\(\mathrm{VAE}\) 架构就是在原本的 \(\mathrm{AE}\) 结构上, 为编码添加合适的噪声, 如图 5-5 所示。首先将 input 输入到编码器, 计算出两组编码: 一组编码为均值编码 \(m=\left(m_1, m_2, m_3\right)\), 另一组为控制噪声干扰程度的方差编码 \(\sigma=\left(\sigma_1, \sigma_2, \sigma_3\right)\), 这两组参数分别通过两个神经网络计算得到。其中方差编码 \(\sigma\) 主要用来为噪音编码 \(z=\left(e_1, e_2, e_3\right)\) 分配权重, 在分配权重之前对方差编码 \(\sigma\) 进行了指数运算,主要是因为神经网络学习出来的权重值是有正负值的,加入指数运算保证分配到的权重是正值。最后,将原编码 m 和经过权重分配后噪声编码进行叠加,得到新的隐变量,再送入解码器。观察图5-5可以看出,损失函数这一项除了之前传统AE的重构损失以外, 还多了一项损失: \(\sum_{i=1}^3\left(\exp \left(\sigma_i\right)-\left(1+\sigma_i\right)+\left(m_i\right)^2\right)\) 。

运用反证法的思想来推敲这个新损失的意义。当不引入这个损失函数时,模型会努力减少生成图片的重构误差来提高图片质量。为了实现这一点,编码器会期望减少噪音对生成图片的影响,降低任务难度。因此,它会倾向于给噪音分配较低的权重。如果没有任何约束限制,网络只需要将方差编码设置为接近负无穷大的值,从而消除噪音的影响。即 (\exp \left(\sigma_i\right) e_i=0), 此时 (m_i) 就等于它本身, 模型就退化成了普通的自编码器,过拟合问题就会卷土重来。尽管此时模型的训练效果可能非常好,但生成的图片往往会非常糟糕。

为了方便理解,可以做一个生活中的类比。将变分自编码器(VAE)的工作过程类比为参加高考的过程。在学生们准备高考的过程中,他们需要进行大量的模拟考试以提高最终的考试成绩,这就像VAE在训练阶段所做的事情。 模拟考试的题目和难度由老师安排,这能够公正地评估学生们的学习能力。类似地,VAE的训练过程中,它生成的数据的分布,即方差编码 σ,

应由某个损失函数(可以理解为“老师”)来决定。如果没有老师的监督,让学生们自己设置模拟考试的难度,他们很可能将试题设得非常简单,以便得高分。这就像VAE在没有适当的损失函数约束时,可能倾向于降低噪声的影响,让模型重构误差尽可能地接近于零。 因此,为了保证VAE在实际应用中的表现,而不是通过降低噪声影响来“投机取巧”,需要引入一个适当的损失函数。这个损失函数就像老师一样,监督VAE的训练过程,确保模型在适当的难度下进行训练,从而能够在复杂的真实世界任务中表现得更好。

所以,除了重构误差,VAE还让所有的矩阵 c 都向标准正态分布看齐,这样就防止了 (\exp \left(\sigma_i\right) e_i=0),进而造成噪声为零的情况,保证VAE模型不会退化成自编码器,如图5-6所示。

图片[6]-变分自编码器(VAE)算法详解-点头深度学习网站

让所有的 \(c\) 都向标准正态分布看齐最直接的方法就是在重构误差的基础上中加入额外的损失。此时, \(\mathrm{KL}\) 散度就派上用场了,可以让 \(p(z \mid x)\) (也就是 \(c\) )和 \(\mathcal{N}(0, I)\) 看齐,相当于一个约束, 确保方差不为 0 。所以加一个约束项 \({KL}\left(q_\theta(z \mid x) \| \mathcal{N}(0, I)\right)={KL}(p(z \mid x)|| p(z))\),这个约束项经过推导即为 VAE 中的第二项损失。推导过程, 参加以下小节。

潜空间

在机器学习和深度学习领域中,由编码器将输入数据映射到的低维向量空间。得到的低维空间被称为潜空间(latent space),因为它包含了输入数据的隐藏特征和表示。

在深度学习中,编码器通常是一个神经网络,它通过学习将高维输入数据(如图像、音频或文本)转换为潜空间中的低维向量表示。这个低维向量表示捕捉了输入数据的重要特征和结构,其中每个维度可能对应着数据的某个抽象特征。

潜空间具有一些有用的属性。首先,潜空间具有较低的维度,因此可以更有效地表示数据,并且可以减少冗余信息。其次,潜空间的向量可以进行数学运算,例如向量加减法,这种运算在潜空间中对应着对输入数据的语义操作,例如在图像中添加或去除特定特征。这使得潜空间成为生成模型和重构模型的重要组成部分。

潜空间在许多机器学习任务中都发挥着重要作用,包括图像生成、图像重构、特征提取和数据压缩等。通过学习潜空间的结构和特征,可以实现更高级别的数据分析和操作。

一个好的潜空间应该具备以下几个特点:

(1)有意义的表示:潜空间中的每个维度应该对应着输入数据的某个有意义的特征。这意味着相似的数据在潜空间中应该更接近,而不相关的数据应该更远离。例如,在图像领域,潜空间的某个维度可以表示图像中的颜色,另一个维度可以表示形状。这种有意义的表示使得在潜空间中的运算和操作更加直观和可解释。

(2)低维度:潜空间的维度应该相对较低,以便有效地表示数据并减少冗余信息。通过将高维数据映射到低维空间,可以提取数据中最重要的特征,并且可以更高效地进行计算和操作。

(3)连续性:潜空间中的向量应该具有连续性,即在潜空间中相邻的向量应该对应着在输入空间中相似的数据。这种连续性使得在潜空间中进行插值或插入新的向量时,能够产生合理和平滑的结果。例如,在图像生成任务中,通过在潜空间中对两个不同的向量进行线性插值,可以生成一个介于它们之间的新图像。

(4)可操作性:潜空间中的向量应该具有可操作性,即可以通过对向量进行数学运算来实现对输入数据的语义操作。例如,在图像生成任务中,可以通过在潜空间中对某个向量的特定维度进行增减操作,来改变生成图像中的某个特征,如颜色、形状等。

(5)一致性:潜空间应该在不同的输入数据之间保持一致,即相同类型的数据在潜空间中应该有相似的表示。这样可以确保潜空间的泛化能力,使得相似的数据具有相似的表示,而不同类别的数据有明显的区分。

一个好的潜空间设计可以使得在该空间中的数据表示更加有效、有意义,并且可以支持各种任务,包括生成、重构、插值和语义操作等。潜空间和图像生成模型之间有密切的关系,潜空间是图像生成模型的关键组成部分之一。

图像生成模型旨在从潜空间中生成逼真的图像。这些模型通常使用生成对抗网络,扩散模型或变分自编码器等方法。在这些模型中,一个重要的步骤是将输入图像映射到潜空间中的向量表示,这个过程通常由编码器完成。编码器将输入图像转换为潜空间中的向量表示,其中每个向量维度对应着图像的某个特征。这个向量可以被看作是图像的隐含表示或特征向量。此特征向量可以被用于进行各种图像操作,例如生成新的图像、重构原始图像或者在潜空间中进行插值操作。

生成模型的另一部分是解码器,它的任务是将潜空间中的向量转换回图像空间。解码器接收潜空间中的向量,并将其解码为逼真的图像。这个过程可以被视为对潜空间向量的逆映射。

通过训练生成模型,可以学习到一个优化的潜空间表示,其中潜空间中的向量可以被解码成高质量的图像。从而可以在潜空间中进行图像操作,例如通过在潜空间中调整特定维度的值来改变图像的特征,或者通过在潜空间中进行插值来生成介于两个向量之间的新图像。

总之,潜空间为图像生成模型提供了一个有效的表示和操作图像的方式,可以通过对潜空间中的向量进行操作来生成和操纵图像。

极大似然估计

极大似然估计(Maximum Likelihood Estimation,MLE)是一个由样本来估计总体的算法,就像我们想根据有限的图片样本估计它总体的潜空间表示。然而,极大似然估计是参数估计方法,而我们求的是概率分布,该如何进行应用呢? 这里需要运用统计建模方法,假设样本 \(p(x)\) 服从某种分布, 对于连续数据最常用的就是高斯分布 \(\mathcal{N}\left(\mu, \sigma^2\right)\) 。当 \(p(x)\) 的分布确定后, 概率分布估计问题就转化为了参数估计问题。因此联合概率分布 \(p(x, z)\) 可以分解为:
$$
L(\theta ; X)=P(X ; \theta)=\prod_{i=1}^n p\left(x_i ; \theta\right)
$$

其中, \(\theta\) 可以看作是 \(\mathrm{z}\) 分布的参数, 上述也被称为似然函数。极大似然估计准则是最大化似然函数, 这等同于最小化负对数似然函数, 取对数是为了将连乘符号变成连加符号, 方便计算, 公式如下:

$$
\hat{\theta}=\arg \max _\theta L(\theta ; X)=\arg \min _\theta-\sum_{i=1}^n \ln p\left(x_i ; \theta\right)
$$

在优化的过程中需要求解关于参数 \(\theta\) 的梯度:
$$
\nabla_\theta L(\theta ; X)=-\nabla_\theta \sum_{i=1}^n \ln p\left(x_i ; \theta\right)=-\sum_{i=1}^n \nabla_\theta \ln p\left(x_i ; \theta\right)
$$

按照梯度下降的方法, 极大似然估计就可以求出参数 \(\theta\), 得到概率分布, 最后采样生成图片。

实际上神经网络的有监督训练与极大似然估计很相似。首先,读者需要明白两者的基本概念:

(1)有监督训练:在有监督训练中,存在一组标签过的训练数据,每个训练样本都有一个对应的标签(或目标值)。目标是训练一个模型,当给定一个新的输入时,能够准确地预测出对应的标签。

(2)极大似然估计:极大似然估计是一种用来估计一个概率模型参数的方法。其基本思想是,给定一组观测数据,应该选择那些使得这组数据出现的可能性(似然性)最大的参数。

现在,让我们来看看它们之间的关系:在许多情况下,神经网络的有监督训练可以看作是在进行极大似然估计。例如,当使用交叉熵损失函数(一种常用于分类问题的损失函数)训练一个神经网络时,实际上就是在对模型的参数进行极大似然估计。因为在这种情况下,训练目标是最小化交叉熵损失函数,这等价于最大化数据的对数似然。简而言之,我们希望找到一组参数,使得在这组参数下,观察到的实际标签出现的可能性达到最大。这也就是为什么说神经网络的有监督训练与极大似然估计的思路相同。它们都是在寻找一组参数,使得给定这组参数,观察到实际数据的可能性最大。

而且,在神经网络的有监督训练中,虽然不直接假设一个显式的数据生成分布,但在使用特定的损失函数(如均方误差或交叉熵)时,实际上隐含地做了一些关于数据和模型错误的分布假设。例如,使用均方误差损失函数通常假设了数据误差遵循高斯分布;而使用交叉熵损失函数则假设了分类任务中数据遵循伯努利或多项分布。

具体来说,对于均方误差,其形式是预测值和实际值之差的平方的期望(或平均值)。如果将这种误差视为随机变量的“噪声”,那么MSE就等价于这种噪声的方差。根据中心极限定理,当大量独立同分布的随机变量叠加时,其和的分布将接近正态分布(也就是高斯分布)。因此,当使用MSE作为损失函数时,隐含地假设了噪声遵循高斯分布。对于交叉熵,它常常用于衡量两个概率分布之间的差异。在二元分类问题中,每个样本只有两种可能的类别,因此其目标值可以看作是一个伯努利随机变量的实现结果。目标就是找到一个模型,其预测的概率分布尽可能接近目标的伯努利分布。所以,当使用交叉熵作为损失函数时,隐含地假设了数据遵循伯努利分布。同样,对于多分类问题,目标值可以看作是多项分布的实现结果,因此使用交叉熵也就隐含了数据遵循多项分布的假设。所以,虽然在神经网络训练的过程中并没有显式地声明这些分布假设,但这些假设确实是损失函数选择的结果,并且对模型的训练和预测有重要影响。

损失函数的选择对模型的训练影响很大,这同样也是极大似然估计存在的一个致命的问题:该方法是有假设存在的,假设了 p(x) 服从某种分布。分布的选择是需要领域知识或先验的,需要对生成过程很了解,否则如果选择的分布和真实分布不一致,那么结果可能很差。真实世界的问题通常是很复杂的,没有人能够完全了解它的生成过程,同时也没有能够描述如此复杂过程的概率分布形式,因此假设的分布基本都是错误的。

隐变量模型

隐变量就是潜空间中向量。它可以作为解决图片生成这一困难问题的跳板,这个思路在数学中非常常见,例如:我们想直接根据变量“a”,求解结果“b”非常困难,而由“a”求解“c”和由“c”求解“b”都很简单,那么可以选择绕开最难的部分,而选择“a →c →b”的求解方法。在图像生成中体现为:根据图片样本直接求解数据分布 p(x) 很难,那么可以通过隐变量实现,例如考虑手写体数字例子,一般在写数字的时候会首先想到要写哪个数字,同时脑子里想象它的样子,然后才是写下来形成图像。这个过程可以总结成两个阶段:先决定数字及其它影响因素,用隐变量 z 来表示;再根据隐变量 z 生成数字图像。这就是隐变量模型,用数学描述为:

$$
P(X)=\int P(X \mid z ; \theta) P(z) \mathrm{d} z
$$

通常假定 \(z\) 服从正态分布 \(z \sim \mathcal{N}(0, I), P(X \mid z ; \theta)\) 可以换成 \(f(z ; \theta)\), 即用一个参数为 \(\theta\) 的函数去计算样本 \(X\) 的概率分布 \(P(X \mid z ; \theta)\) 。这里采用条件分布形式是因为它可以显式的表明\(X\) 依赖 \(z\) 生成。隐变量模型把概率密度估计问题转化函数逼近问题。首先分开解释这两部分:

(1)概率密度估计:这是一个统计问题,目标是从有限的样本数据中估计出整个概率分布。对于复杂的、多维的数据,直接估计这个分布可能是困难的。

(2)函数逼近:这是一个优化问题,目标是找到一个函数,使其在某种意义下尽可能地接近给定的目标函数。在神经网络中,这个函数通常是通过一个可微分的参数化模型(比如深度神经网络)来表示的。

隐变量模型,如变分自编码器,可以把概率密度估计问题转化为函数逼近问题。在VAE中,并不直接估计数据的概率密度,而是假设存在一个隐含的潜在空间,数据是由这个潜在空间中的点通过一个可微分的生成网络生成的,即VAE的解码器。这个生成网络可以被看作是一个函数,它把潜在空间中的点映射到数据空间。我们的目标是找到这个生成网络的参数,使得由它生成的数据的分布尽可能地接近真实数据的分布。这就把一个概率密度估计问题转化为了一个函数逼近问题。

这样的做法有几个优点。首先,函数逼近问题可以通过诸如梯度下降等优化方法来解决。其次,可以利用深度神经网络的强大表示能力来建模复杂的、高维的数据分布。最后,通过学习一个潜在空间,可以得到数据的一种低维表示,这对于许多任务,比如生成模型、异常检测等,都是有用的。

隐变量模型背后的关键思想是: 任何一个概率分布经过一个足够复杂的函数后可以映射到任意概率分布。如示例中, \(z\) 服从标准高斯分布, 采样后经过函数 \(f(z ; \theta)\) 的变换后可以变成手写体数字的真实分布 \(P(X)\) 。

通过隐变量模型, 极大似然估计的问题已经被绕过去了, 不再需要指定复杂的概率分布形式也不怕出现分布不一致的情况。只需要求解函数 \(f(z ; \theta)\) 即可, 这个函数看似很难求解,实际上就是很难求解, 不过我们有神经网络这一利器, 深度学习最有魅力的一点就是拟合能力, 但凡直接求解很困难的问题, 都可以交给神经网络进行拟合。

下面采用极大似然的思想去优化隐变量模型。因为 \(P(X \mid z ; \theta)\) 是确定性函数, 最大化 \(P(X)\) 等于最大化 \(P(z)\) 。我们想要的是从 \(P(z)\) 采样的 \(z\) 的概率如果很大, 则它生成的 \(X\) 出现在数据集的概率也很大。隐变量模型的负对数似然函数为:

$$
L(\theta ; X)=-\sum_{i=1}^n \ln p\left(x_i ; \theta\right)=-\sum_{i=1}^n \ln \int p\left(x_i \mid z ; \theta\right) p(z) \mathrm{d} z
$$

关于 \(\theta\) 的梯度为:
$$
\nabla_\theta L(\theta ; X)=-\sum_{i=1}^n \nabla_\theta \ln \int p\left(x_i \mid z ; \theta\right) p(z) \mathrm{d} z=-\sum_{i=1}^n \frac{\int \nabla_\theta p\left(x_i \mid z ; \theta\right) p(z) \mathrm{d} z}{\int p\left(x_i \mid z ; \theta\right) p(z) \mathrm{d} z}
$$

根据上述的梯度公式就可以优化参数, 得到最后的隐变量模型。
但隐变量模型存在问题: 计算 \(\nabla_\theta L(\theta ; X)\) 的过程中需要计算分子和分母的积分, 为了使得 \(z\) 能表达更多的信息, 通常假设 \(z\) 是一个连续的随机变量。在这种情况下, 一般无法直接求解准确值,会存在计算困难的问题。

 蒙特卡洛采样

隐变量模型在计算梯度时存在积分难计算的问题。针对求积分问题,很难计算准确值,因此通常采用蒙特卡罗采样去近似求解。

原来的积分可以写成期望的形式 \(\int p(x \mid z ; \theta) p(z) \mathrm{d} z=\mathbb{E}_{z \sim p(z)}[p(x \mid z ; \theta)]\), 然后利用期望法求积分, 步骤如下。
(1) 从 \(p(z)\) 中多次采样 \(z_1, z_2, \cdots, z_m\);
(2) 根据 \(p(x \mid z ; \theta)\) 计算 \(x_1, x_2, \cdots, x_m\)
(3) 求 \(x\) 的均值。用数学表达为:
$$
\int p(x \mid z ; \theta) p(z) \mathrm{d} z=\mathbb{E}_{z \sim p(z)}[p(x \mid z ; \theta)] \approx \frac{1}{m} \sum_{j=1}^m p\left(x_j \mid z_j ; \theta\right)
$$

通过对 \(z\) 多次采样, 可以计算 \(\nabla_\theta L(\theta ; X)\) 的近似值。简单来说, 蒙特卡洛采样就是通过样本的均值来近似总体的积分。

蒙特卡罗采样存在的问题是:采样次数一般需要很大。主要是由两个因素引起的:

(1)高维度:对于高维问题,由于“维度的诅咒”,可能需要指数级的采样数才能在所有维度上获得足够的覆盖。这是因为在高维空间中,大部分的体积都在靠近边界的区域,所以需要大量的样本才能精确地估计整个空间的性质。

(2)稀疏区域:如果感兴趣的分布在某些区域中非常稀疏,那么大多数的蒙特卡罗样本可能都会落入不关心的区域,而真正关心的区域可能会被严重地欠采样。这会导致估计结果严重偏离真实值。

解决这两个问题的方法可以缩小 \(z\) 的取值空间。缩小 \(p(z)\) 的方差 \(\sigma^2\), 那么 \(z\) 的采样范围会缩小, 采样的次数 \(m\) 也不需要那么大。同时, 也可能把生成坏样本的 \(z\) 排除, 生成更像真实样本的图像。这其实就是下面要介绍的 VAE 的原理。

变分推断

继续上一节的问题, 怎么能缩小 \(z\) 的取值空间呢? 原来 \(z\) 从先验概率分布 \(p(z)\) 中采样,现在可以考虑从 \(z\) 的后验概率分布 \(p(z \mid X)\) 中采样。具体来说, 给定一个真实样本 \(X\), 假设存在一个专属于 \(X\) 的分布 \(p(z \mid X)\) (后验分布), 并进一步假设这个分布是独立的、多元的正态分布。

如何理解后验概率 \(p(z \mid X)\) 会比先验概率 \(p(z)\) 更好呢? 在变分自编码器中, “后验概率”通常是指在给定观察数据的情况下, 隐变量的概率分布, 而 “先验概率” 则是在没有观察数据的情况下, 隐变量的概率分布。

VAE 的目标之一就是通过学习来逼近后验概率。在训练过程中, 希望通过调整模型参数, 使模型生成的数据的分布接近真实数据的分布, 这也就相当于逼近隐变量的真实后验概率。

然后,为什么说后验概率会比先验概率更好呢?这是因为后验概率包含了更多的信息。先验概率只反映了在没有观察数据之前对隐变量的知识或者假设,它通常被设置为一种简单的分布,如高斯分布或者均匀分布。而后验概率则是在观察到数据之后,对隐变量的最新认识,它包含了数据的信息。

例如,假设我们的任务是对人脸图片进行建模,隐变量可能代表一些人脸的特性,如性别、年龄等。在没有看到任何图片的情况下,可能假设所有的性别和年龄都是等可能的,这就是先验概率。但是当看到一些图片之后,可能会发现实际上某些性别或者年龄的人脸图片更常见,这就是后验概率。

因此,当我们说后验概率比先验概率更好,其实是说,后验概率包含了更多的来自于数据的信息,能够更准确地反映真实世界的情况。在变分自编码器中,编码器的目标就是学习表示后验概率分布。

从数学角度出友, 如何求出后验概率分布 \(p(z \mid X)\) 呢? 求隐变量的后验分布是变分推断的一个核心问题。

一般是无法准确求出后验分布的, 但是变分推断可以用另一个分布 \(q_\theta(z \mid X)\) 近似估计 \(p(z \mid X)\), 然后从 \(q_\theta(z \mid X)\) 中采样来近似从 \(p(z \mid X)\) 中采样。这种方法是用一个函数近似另一个函数,其实就是用神经网络来近似概率分布参数。用变分法的术语来说,变分推断的主要思想是通过优化来近似复杂的概率分布。这个方法的名字 “变分” 来自于微积分中的变分法,这是一种数学方法,用于寻找函数或者泛函(函数的函数)的极值。

在变分推断的背景下, 我们有一个复杂的概率分布, 通常是后验概率分布 \(p(z \mid X)\), 这里 \(z\) 是隐变量, \(X\) 是观察到的数据。目标是找到一个相对简单的分布(比如高斯分布),称其为 \(q_\theta(z \mid X)\), 用它来近似真实的后验分布。其中, \(\theta\) 表示分布的参数, 需要找到合适的 \(\theta\) 来最大化这种近似的准确性。

那么, 如何度量这种 “近似” 的准确性呢? 这就需要用到 KL 散度, 它是一种衡量两个概率分布之间 “距离” 的方法。目标就是找到参数 \(\theta\), 使得 \(q_\theta(z \mid X)\) 和 \(p(z \mid X)\) 之间的 \(\mathrm{KL}\)散度最小。

然后, 这个最小化问题可以通过梯度下降等优化算法来求解。在每一步中都会计算 KL 散度关于 \(\theta\) 的梯度(这就是 “变分”),然后沿着梯度的负方向更新 \(\theta\) ,以减小 KL 散度。这个过程就像在函数空间中“下山”,因此被称为函数空间的梯度下降。

所以,变分推断就是一种用优化的方式来逼近复杂的概率分布的方法。通过在函数空间中进行梯度下降,找到一个可以用来近似真实分布的简单分布。但是,还有一个很大的问题:

\(p(z \mid X)\) 是未知的, 所以无法直接计算 \(\mathrm{KL}\) 散度。解决这个问题的方法是通过引入一个叫做证据下界 (Evidence Lower Bound, ELBO) 的量。ELBO 是模型对数似然的一个下界, 它与 \(\mathrm{KL}\) 散度的和是一个常数, 这个常数就是观测数据的对数似然。因此, 最大化 ELBO 等价于最小化 KL 散度。
ELBO 可以写成以下形式:
$$
\mathrm{ELBO}=E_{q_\theta(z \mid X)}[\log p(X \mid z)]-K L\left(q_\theta(z \mid X) \| p(z)\right)
$$

其中第一项 \(E_{q_\theta(z \mid X)}[\log p(X \mid z)]\) 是重构误差, 代表了生成的数据与实际数据的相似程度, 具体来说, \(X \sim q_\theta(z \mid X)\) 表示有一个 \(X\) 可以根据分布 \(q_\theta(z \mid X)\) 采样一个 \(z\), 这个过程可以理解为把 \(X\) 编码成 \(z\), 此过程被称为 VAE 模型的编码器。 \(p(X \mid z)\) 表示根据 \(z\) 生成输出结果,此过程被称为 VAE 模型的解码器。整体表示给定 \(x\) 编码成 \(z\) 再重构得到输出结果, 这个过程的期望, 被称为重构误差。如果这个期望很大, 表明得到的 \(z\) 是 \(X\) 的一个好的表示, 能够抽取 \(X\) 足够多的信息来重构输出结果, 让它与 \(X\) 尽可能相似。第二项 \(\mathrm{KL}\left(q_\theta(z \mid X) \| p(z)\right)\)是 \(q_\theta(z \mid X)\) 和先验分布 \(p(z)\) 的 KL 散度, 代表了隐变量的分布偏离先验分布的程度。

可以看到, 计算 ELBO 并不需要知道后验分布 \(p(z \mid X)\) 的具体形式, 只需要知道数据的生成模型 \(p(X \mid z)\) 和隐变量的先验分布 \(p(z)\), 而这两者通常都是可以设定的, 所以可以计算。因此, 可以通过最大化 ELBO 来实现变分推断。

最后, 证据下界的推导过程是基于 Jensen 不等式和 KL 散度的性质, 了解即可, 不要求掌握。

先定义一个模型的对数似然:
$$
\log p(X)=\log \int p(X, z) \mathrm{d} z
$$

其中 \(z\) 是隐变量, \(X\) 是观察数据。
再引入变分分布 \(q_\theta(z \mid X)\), 然后对上式两边乘以 \(q_\theta(z \mid X)\) 并对 \(z\) 积分, 得到:
$$
\log p(X)=\log \int q_\theta(z \mid X) \frac{p(X, z)}{q_\theta(z \mid X)} \mathrm{d} z
$$

由于对数函数是凹函数, 这里可以使用 Jensen 不等式, Jensen 不等式说明对于凹函数 \(f\)和随机变量 \(Z\), 有 \(E[f(Z)] \leq f(E[Z])\) 。所以:

$$
\log p(X) \geq \int q_\theta(z \mid X) \log \frac{p(X, z)}{q_\theta(z \mid X)} \mathrm{d} z
$$

上述不等式的右边,就是定义的 ELBO:
$$
\mathrm{ELBO}=E_{q_\theta(|| X)}[\log p(X \mid z)]-K L\left(q_\theta(z \mid X) \| p(z)\right)
$$

它由两部分组成, 第一部分 \(E_{q_\theta(z \mid X)}[\log p(X \mid z)]\) 是对数似然的期望, 第二部分 \(K L\left(q_\theta(z \mid X) \| p(z)\right)\) 是变分分布与先验分布之间的 \(\mathrm{KL}\) 散度。

所以,ELBO实际上是对数似然的一个下界。在变分推断中,试图最大化ELBO,这等价于最小化变分分布与真实后验分布之间的KL散度,从而使得变分分布尽可能接近真实的后验分布。

实际上,ELBO就是VAE的损失函数,VAE的训练目标就是最大化ELBO(证据下界)。负ELBO由两部分组成:第一部分是期望的重构误差,它衡量的是模型生成的数据与真实数据的匹配程度;第二部分是KL散度,它衡量的是隐变量的分布偏离先验分布的程度。

重构误差可以用各种不同的方式来计算,例如使用均方误差或者交叉熵损失。至于KL散度,由于通常假设先验分布是标准正态分布,所以KL散度可以用隐变量的均值和方差来显式计算。值得注意的一点是,在VAE简明推导中提到的KL散度损失是:

$$
\frac{1}{2} \sum_{i=1}^l\left(\exp \left(\sigma_i\right)-\left(1+\sigma_i\right)+\left(\mu_i\right)^2\right)
$$

它是在假设隐变量服从高斯分布时的结果。在变分自编码器中, 通常会假设隐变量 \(z\) 的先验分布是标准正态分布, 即 \(p(z)=\mathcal{N}(0, I)\) 。还会假设编码器给出的后验分布也是一个高斯分布, 即 \(q_\theta(z \mid X)=\mathcal{N}\left(\mu, \sigma^2 I\right)\), 其中 \(\mu\) 和 \(\sigma\) 是由神经网络给出的。在这种情况下, \(q_\theta(z \mid X)\) 和 \(p(z)\) 之间的 KL 散度可以显式计算出来, 结果就是上述公式。其中: \(\mu_i\) 是隐变量 \(z\) 第 \(i\) 个维度的均值, \(\sigma_i\) 是第 \(i\) 个维度的标准差的对数 (在实际实现中, 神经网络直接输出的通常是 \(\log \sigma^2\), 为了保证其非负), \(l\) 是隐变量的维度。

下面给出具体的推导, 首先, 两个高斯分布之间的 KL 散度的公式为:
$$
{KL}\left(\mathcal{N}\left(\mu_1, \sigma_1^2\right) \| \mathcal{N}\left(\mu_2, \sigma_2^2\right)\right)=\frac{\left(\mu_1-\mu_2\right)^2+\sigma_1^2-\sigma_2^2+2\left(\log \sigma_2-\log \sigma_1\right)}{2 \sigma_2^2}
$$

在 VAE 中, 设定先验分布 \(p(z)=\mathcal{N}(0,1)\), 即 \(\mu_2=0, \sigma_2^2=1\), 而后验分布 \(q_\theta(z \mid X)=\mathcal{N}\left(\mu, \sigma^2\right)\), 即 \(\mu_1=\mu, \sigma_1^2=\sigma^2\), 将这些代入, 可以得到:

这就是 KL 散度的公式。但是, 由于通常使用 \(\log \sigma^2\) (记作 \(\sigma\) ) 作为神经网络的输出 (为了确保 \(\sigma^2\) 的非负性), 可以对公式再做一些变换:
$$
\mathrm{KL}\left(q_\theta(z \mid X) \| p(z)\right)=\frac{\mu^2+\mathrm{e}^\sigma-1-\sigma}{2}
$$

这就是 VAE 论文中所给出的 KL 散度项的公式。如果有 \(l\) 个隐变量, 那么整个 KL 散度项就是所有维度上的 KL 散度之和, 公式如下:

$$
\sum_{i=1}^l\left(\frac{1}{2}\left(\mu_i^2+\exp \left(\sigma_i\right)-1-\sigma_i\right)\right)
$$

这就是在 VAE 损失函数中需要最小化的 KL 散度项的公式。

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容