深度理解变分自编码器(VAE) | 从入门到精通

前言 本文介绍了深度理解变分自编码器(VAE)的系列发展及相应的局限性。

 

本文转载自CVHub

作者丨派派星

 

欢迎关注公众号CV技术指南,专注于计算机视觉的技术总结、最新技术跟踪、经典论文解读、CV招聘信息。

 

 

导读

本文是笔者早前写过的一篇关于 VAE 的读书笔记,先整理出来分享给大家。作为一名业余的技(生)术(活)爱(所)好(迫)者,为了不在35岁前被社会淘汰,笔者也只能时不时跟进下最前沿的技术,包括但不仅限于这两年大火的 AIGC 背后的底层技术——扩散概率模型。这是一类相比于 GAN 更先进的生成模型,由 Sohl-Dickstein 等人于2015年首次提出。然而,真正使其爆火的里程碑应该是 DDPM,即去噪扩散概率模型的出现。因为自 DDPM 面世以来,人们对扩散模型产生了浓厚的兴趣,不断有新的工作涌现出来,并成功的扩展到多个领域,包括但不仅限于语音建模、文本到语音、文本到图像以及多变量时间序列预测等等。

 

作为一个生成模型,扩散模型同样有许多独特而有趣的特性。例如,经过训练的模型能够轻松的执行 inpainting 和 zero-shot denoising 等任务。此外,DDPM 中使用的变分约束突出了与变分自动编码器和神经压缩的进一步联系。因此,在这篇文章中,我想先从简单的变分自编码器讲起,后续有时间再单独出一篇关于扩散模型的讨论,通过联系不同模型之间的关系,进一步提出关于未来研究的想法。

 

以下是本文大纲:

 

一、基础知识回顾
  1. Latent Variable
  2. Variations
  3. Gaussian Mixture Model
  4. Conditional Probability
  5. KL divergence
  6. Maximum Likelihood Estimate
二、自编码器
  1. 编解码器简述
  2. 从 PCA 开始谈起
  3. PCA 到 AE 的转变
  4. 自编码器有哪些应用?
  5. 自编码器的局限性在哪里?
三、变分自编码器
  1. 为什么要引入 VAE?
  2. VAE 与 AE 的区别?

 

基础知识回顾

Latent Variable

latent variable,隐变量或潜在变量,也称为latent code。
A latent variable is a variable that is inferred using models from observed data.
隐变量是指通过模型从观测数据中推断出来的变量。比如,我们将一个输入对象送入一个神经网络的编码层(Nerual Network Encoder, NN-Encoder),得到的由隐含层输出的向量就可以称作 latent variable。

Variations

Variations,即变分法。在简述变分之前我们应该了解什么是泛函?回顾下从小到大我们所学习过的函数,它是将一个给定的输入数值x,经过一系列的变化f(x),从而得到输出数值y。注意这里我们输入的是一个数,输出的也是一个数。那有没有这种情况,如果我们的自变量是一个函数而不是一个数值?最经典的问题便是,给定两个定点A和B,我们从A点可以经过任意一条路径到达B点,求在什么样的路径下使得A点到B点的时间最短?到这里大多数人都有答案了——两点之间直线段最短。像这种输入变量是一个函数,输出变量是一个数值的函数,称为泛函。泛函通俗点理解就是函数的函数。
针对上图,我门先求出点A(x1, y1)到点B(x2, y2)之间任意路径长度的表达式。任取一小段微元,根据勾股定理我们可以得出:,其中我们将这条曲线定义为。现在让我们对函数y进行求导,可以得到:,公式变形下就得到:,我们将其带入到第一条公式,然后公式左右两边同时开方,可以得到:,到这里我们便求出了一小段微元的长度了。接下来我们只将对x1到x2区间内所有的微元段累加起来便能得到总的路径长度为:
在上面的式子中, 便是一个泛函。其中被积函数 我们称为 Lagrange Function,即拉格朗日函数 。现在我们的任务便是要寻找一个合适的函数 使得泛函 的取值最小。
变分法便是用于求泛函数的极值。下面就不展开了,有兴趣的可以自行查阅相关资料。这里主要说一点的就是 VAE 中 V 是怎么来的,笔者认为应该只是计算的过程中用到了变分法的思想去求解 ,所以就取名叫 VAE。

Gaussian Mixture Model

Gaussian Mixture Model,即高斯混合模型。生成模型比较主流的三个模型为:隐马尔可夫模型HMM、朴素贝叶斯模型NB和高斯混合模型GMM。这里我们主要为大家介绍下GMM。
混合模型是一个可以用于表示在总体分布中含有N个子分布的概率模型,它表示了观测数据在总体中的概率分布。利用混合模型计算总体分布概率时我们并不需要知道原始观测数据中子分布的信息。
如上所示, 代表图中黑色的分布曲线。以前学过《Signal Processing》的人都知道,由 Fourier Theory 可得,任意一个随时间做周期性变化的波,都可以分解为一系列不同频率、不同振幅、不同相位的正弦波。同样地,我们也可以用多个正态分布的叠加去逼近任意一个分布。

Conditional Probability

Conditional Probability:条件概率。定义两个事件A和时间B,求A和B同时发生的概率:

KL divergence

KL divergence:KL散度又称为KL距离或相对熵,用于衡量两个概率分布之间的距离。给定真实分布 和理论分布 ,我们将它们之间的KL散度公式定义为:
 
此外,关于 KL 散度的一些性质如下:
  • KL散度是不对称的:因为P到Q的距离不等于Q到P的距离,即KL(P||Q)≠KL(Q||P)。这很容易造成model collapse即模式坍缩——模型倾向于生成一些比较容易骗过判别器的样本,加快模型的收敛,从而导致生成的多样性变差,生成出来的效果也比较差,相当于走捷径。
  • 当且仅当两个分布完全一致时,KL散度等于0。

Maximum Likelihood Estimate

Maximum Likelihood Estimate,MLE:极大似然估计。要理解什么是极大似然估计,我们要先理解什么是“似然”,它同一般的概率事件又有啥区别?给定一个函数 , 代表样本点, 表示参数:
  • 当 为常量, 为变量时,我们称 为关于 的概率函数;
  • 当 为常量, 为变量时,我们称 为关于 的似然函数;
极大似然估计中样本点的采样都必须满足 ,它寻找的是使得样本点 能够以最大概率发生的 的取值。

自编码器

在正式介绍 VAE 之前,我们先简要介绍下什么是 AE。

编解码器简述

通常,我们都会将输入图片送入NN Encoder,得到一个latent code,通常这个latent code的维度是远小于输入对象的维度的,它是输入对象的紧凑表示。接下来,我们将这个latent code送入NN Decoder进行解码,输出经过重构过的原始对象。
Auto-Encoder自编码器是1986年由Rumelhart 提出,可用于高维复杂数据的处理, 它促进了神经网络的发展。自编码神经网络是一种无监督学习算法(训练示例未标注),它使用了BP反向传播算法,致力于使输出与输入越接近越好。
AE网络一般有两个特性:
  • dim(Hidden layer) << dim(Input layer),隐层维度应该远小于输入的维度;
  • 解码层的Output用于重构Input,所以我们应该minimizer(Reconstruction error(Input, Output)),即最小化输入和输出之间的重构误差。
AE的算法描述:
  • Encoder负责将输入数据进行压缩,将n维输入数据通过Hidden layer压缩成m维的数据(m << n),即通过编码器学习一组参数,得到一个latent code;
  • Decoder负责还原数据,在需要用到的时候尽可能地以损失最小的方式恢复原始数据。
AE应用范围一般,但扩展能力很强,可以应用于机器学习中的数据降维、特征抽取和数据可视化分析等,也可扩展并应用于生成模型当中。

从 PCA 开始谈起

PCA 和 SVD 本质上也是一种矩阵降维技术。PCA 通过将输入进行正则化,减去平均值,然后输入到只有一个 hidden layer 的 NN,得到 latent code,最后再直接解码回去得到输出。其主要成分是输入变量的线性组合,其目标同样是希望输出与输入要越接近越好。

PCA 到 AE 的转变

简单的观察下PCA,我们可以发现,它其实只是用了一个hidden layer去学习简单的线性变化,学习能力非常有限。学过Neural Network的人大概都知道,网络的学习能力在很大程度上取决于网络的深度和宽度:
  • CNN中标准的block组合无非是一个Conv+BN+ReLU,这是一个标准的非线性变换模块。网络越深,代表非线性映射的能力越powerful,意味着网络可以学习到更加复杂的变化,从而可以更好的拟合输入的特征;但是,网络加深到一定程度则会带来梯度不稳定,造成网络退化的现象,从而导致性能下降。于是,ResNet便出现了,引入残差映射,可以使梯度更好地回传,从而使训练深层网络变得可能。
  • NN中的每一层hidden layer都可以学习到“知识”,比如第一层hidden layer负责编码诸如点、线、边缘等浅层信息;第二层hidden layer编码简单点的纹理、形状等信息;第三层hidden layer编码诸如眼睛、鼻子等目标的形状...,然后逐层学习,不断地提取抽象的特征,一气呵成,最终学会了辨识花草树木、飞禽走兽等等。
  • 那问题来了,既然网络的深度这么重要,那增加网络的宽度又有啥作用?这个可以这么理解,上面一点提到说每一层hidden layer可以学习不同的特征,举个例子,比如颜色、方向、纹理这三个。增加网络的宽度意味着同一个hidden layer有着更多的神经元,每一个神经元代表一种颜色,一个方向,一种纹理,组合起来便可以学习到更多不同的颜色信息,各个不同的方向以及不同频率的条纹信息。
总的来说就是,网络越深,能够学习到更加抽象的高级语义特征;而网络越宽,则能够让每一层的hidden layer学习到更加丰富的特征表示。所以,沿着这个思路,我们是不是可以将PCA改造下,提升下性能?于是Deep Auto-Encoder便出现了,如下图所示:
下面我们看下通过增加层数的效果,可以看出由自编码器Reconstructed过的图像变得更加清晰了:

 
 
 
 

自编码器有哪些应用?

Auto-Encoder一般的应有有文本检索,以图搜图,还可用于预训练。下面以以图搜图为例。
直觉上我们想要通过一张图片,然后去数据库中寻找跟这张图片类似的图片我们会怎么做?一种直白思路便是计算目标图片与每一张图片像素与像素之间的距离(如欧式距离)来搜寻图片,所得到的结果是这样子的:
可以看出搜索出来的结果啼笑皆非。下面展示下用AE进行相似图片搜索的结果,可以看出搜索的结果好了很多,但是得到的图片会比较模糊:
 
另外,Auto-Encoder还可以用于CNN上,也就是我们常看到的类似U-Net的架构:

自编码器的局限性在哪里?

上面我们通过AE构造出一个比PCA更加清晰的自编码器模型,但这并不是真正意义上的生成模型。对于一个特定的生成模型,它一般应该满足以下两点:
  • 编码器和解码器是可以独立拆分的(类比GAN的Generator和Discriminator)
  • 固定维度下任意采样出来的编码,都应该能通过解码器产生一张清晰且真实的图片
这里解释下第二点。如下图所示,我们用一张全月图和一张半月图去训练一个AE,经过训练,模型能够很好地还原出这两张图片。接下来,我们在latent code上中间一点,即两张图片编码点中间处任取一点,将这点交给解码器进行解码,直觉上我们会得到一张介于全月图和半月图之间的图片(比如阴影面积覆盖3/4的样子)。然而,实际当你那这个点去decode的时候你会发现AE还原出来的图片不仅模糊而且还是乱码的。
为什么会出现这种现象?一个直观上的解释是AE的Encoder和Decoder都使用了DNN,DNN是一个非线性的变换过程,因此在latent space上点与点之间transform往往没有规律可循。
如何解决这个问题呢?一个思想就是引入噪声,扩大图片的编码区域,从而能够覆盖到失真的空白编码区。其实说白了就是通过增加输入的多样性从而增强输出的鲁棒性。当我们给输入图片进行编码之前引入一点噪声,使得每张图片的编码点出现在绿色箭头范围内,这样一来所得到的latent space就能覆盖到更多的编码点。此时我们再从中间点抽取去还原便可以得到一个我们比较希望得到的输出,如下所示:
 
虽然我们为输入图片增添了一些噪声使得latent space能够覆盖到比较多的区域,但是还是有不少地方没有被覆盖到,比如上图右边黄色的部分因为离得比较远所以就没编码到。因此,我们是不是可以尝试利用更多的噪音,使得对于每一个输入样本,它的编码都能够覆盖到整个编码空间?只不过这里我们需要保证的是,对于源编码附近的编码我们应该给定一个高的概率值,而对于距离原编码点距离较远的,我们应该给定一个低的概率值。没错,总体来说,我们就是要将原先一个单点拉伸到整个编码空间,即将离散的编码点引申为一条连续的接近正态分布的编码曲线,如下所示:
到这里,我们已经不知不觉到来到了 变分自编码器VAE 的核心思想腹地。下面我们将详细地叙述VAE的模型架构。

变分自编码器

为什么要引入 VAE?

首先,我们先介绍下VAE的模型架构:
在上面我们也介绍过了,VAE就是在原本的AE结构上,给编码添加合适的噪声。首先我们将input输入到NN Encoder,计算出两组编码:一组编码为均值编码 ,另一组为控制噪声干扰程度的方差编码 。方差编码 主要用来为噪音编码 分配权重,图中在为 分配权重之前为方差编码 套上一层指数运算,只要原因是因为NN学习出来的权重值是有正负值的,所以这是为了保证分配到的权重是正值;最后,我们将原编码 和经过权重分配后噪声编码进行叠加,就得到了新的latent code,然后再送入NN Decoder。观察上图可以看出,损失函数这一项除了之前传统AE的 reconstruction error 以外,还多出了下面一项:
 
为什么要加这一个loss?利用反证法的思想我们来推敲一遍——如果不添加这个损失函数,那么模型为了保证所生成出来的图片质量越高(因为我们最小化了construction error),那么编码器肯定希望噪声对自身生成的图片的干扰越小越好,于是分配给噪声的权重越低越好。如果不加约束限制的话,网络只需要将方差编码设置为接近负无穷大的值( )即可以消除噪声带来的影响。这会带来一种什么现象?就是你会发现它训练得很好,但是往往生成的图片很差。这样的话那我们还这么费劲地引入这个噪声做啥?

 

逆向思维思考完,我们再来正面的理解下,为什么加入这个辅助的loss就有用?公式怎么得到的先不讨论,后面有附录给你参考。现在我们根据上面给出的公式对 进行求导,可得 ,令其等于0可求出当 处取得极小值,这样一来便可以约束方差编码不会一路开挂似的走向负无穷大,相当于起到正则化约束的作用。

 

从文字上解释完,我们再从几何上去观察下:
这里指数函数 画出来就是蓝色的曲线,而红色线条就是 ,于是 就是蓝色曲线减去红色线条,得到的是图中绿色的曲线,可以显而易见地看到它的最小值为0。

 

文字和几何讲完还是理解不了的话,我这里再举一个简单的例子帮助大家理解下:我们可以把VAE正在做的这件事情比作是在参加高考。一般为了能够真正在考场取得好成绩(模型预测),我们在平常的学习生活中需要做各式各样的测试(模型训练)。这些测试题一般是由老师布置给我们,考试难度(方差编码σ)也应该由老师来定,因为只有这样我们才能客观的检验我们的学习能力。假如没有老师监督(辅助loss)的话,而是让我们(网络)来决定考题的难度(分配给噪声的权重),那么我们肯定是偏向于让测试题难度降到最低(使噪声影响最小),最好是一点难度(噪声)都没有啦,从而能够考满分(使最终的重构误差为0)。因此,为了能够真正在高考上取得好成绩,而不是以这种投机取巧的方式混日子,所以我们必须引入老师(辅助的loss)这个中间人来监督这个课堂测试(训练过程)的难度。

 

其次,我们深入理解下VAE的原理:VAE是一种无监督的生成模型,其理论基础是建立在高斯混合模型之上。
由VAE的模型结构,我们可以看到噪声编码 是由一个标准正态分布所产生的向量,我们对这个分布随机采样 个点,其中 服从多项式分布 。每采样一个点 ,我们将其对应到一个高斯分布 ,于是一个多项式分布利用混合模型就可以表示为:
 
这里,经过以上操作,我们便可以将原先离散的、存在大量失真区域的编码方式,转换成连续有效的编码方式。

 

既然我们得出了 的表达式,下面我们说下如何求解它。这里 是已知变量, 是未知的变量,由于 ,所以转换成求 和 这两个函数的表达式。

 

第一步,我们利用NN Decoder来求解 和 ,等价于求出了 ;
 
第二步,我们利用NN Encoder来求解 ,其中 可以表示任何的分布。
这里NN Encoder的作用便是辅助NN Decoder 求解出 ,也是整个VAE算法的核心。
VAE所需要求解的目标表达式为:,原则上我们希望这个分布 越大越好,根据最大似然估计法,这等价于:
 
给定任意一个分布 ,我们有 ,于是可以推导出:
上面式子右边那一项为 和 这两个分布的KL散度距离,根据KL散度公式的性质,我们可以知道右边项恒大于等于0,于是我们找到了 的一个下确界:
 
这里,我们将这个下界Lower bound记为:
 
带入原式子,可写成:
有趣的地方来了,原本我们是求使得 最大化的 ,现在转换成同时求 和 ,是不是很莫名其妙怎么搞这么多操作还引入多一个求解变量出来了?下面我们观察下这个 和 之间的关系:
 
精髓来了,根据公式 ,当我们固定 时,由于 是固定的,所以 也是固定,那么 也就固定住了【对应上图蓝色线段】。而根据上面的推导,我们有:
 
如果此时我们通过调节 ,使得 越来越高,同时KL散度会越来越小。当我们调节到 与 这两个分布完全一致时,KL散度就等于0,此时 就完全等价于 .
简而言之就是,无论 的值如何,我们总能通过调节 使得 等于它,又因为 是 的下确界,所以求解 最终就可以等价为求解: .
从宏观角度来看,调节 就是调节NN Decoder;调节 就是调节NN Encoder 于是,VAE模型的算法便是:Decoder每改进一次,Encoder就调节成跟其一致,并且利用约束项迫使Decoder在训练的时候“只能前进,不能后退”。
下面继续求解:
 
现在又可以将 转化为求解上式左半部分KL散度的最小值,以及右半部分的最大值,我们将其记为 和 .
先看 ,我们将这个KL散度公式进行展开,得到的其实就是约束项:
 
至于如何得到的,由于篇幅有限,有兴趣的读者可参考《Auto-Encoding Variational Bayes》中的附录章节 Appendix B。
再看下 ,我们可以将其表达为:
 
上面的期望的含义可以表述为:在给定NN Encoder输出 的情况下解码器输出 的值要尽可能地高。如果不考虑方差的话,这其实就类似于一个Auto-Encoder的损失函数。
 
最后,再让我们一起来讨论下VAE的局限性。虽然VAE比普通的AE模型训练出来的效果要好很多,但是训练过VAE模型的人都知道,它生成出来的图片相对GANs那种直接利用对抗学习的方式会比较模糊,这是由于它是通过直接计算生成图片和原始图片之间的均方误差,所以得到的是一张“平均图像”。

VAE 与 AE 的区别?

这里仅列举三点主要区别:
  • AE中隐层表示的分布是未知的,而VAE中隐变量是服从正态分布的;
  • AE中学习的仅仅是NN Encoder和Decoder,而VAE还学习了隐变量的分布,即高斯分布的均值和方差;
  • AE只能从1个样本x,得出对应的重构过的x;而VAE学习了隐变量z所服从的高斯分布的参数,便可以源源不断地产生新的z,从而生成新的样本x。
 
欢迎关注公众号CV技术指南,专注于计算机视觉的技术总结、最新技术跟踪、经典论文解读、CV招聘信息。

 

 

QQ交流群:444129970。群内有大佬负责解答大家的日常学习、科研、代码问题。

 

模型部署交流群:732145323。用于计算机视觉方面的模型部署、高性能计算、优化加速、技术学习等方面的交流。

 

其它文章
 

 

posted @ 2023-02-16 19:56  CV技术指南(公众号)  阅读(3648)  评论(1编辑  收藏  举报