跳转至

生成模型底层原理

在看了无数文章之后的大彻大悟,故按照自己的理解总结了一下生成模型的底层原理。

包括:VAE、Diffusion、GAN、FLOW、所有生成式语言模型

生成模型的训练目标是什么?

在图像领域,一个好的生成模型应该尽可能地生成与给定图像(大部分情况下是真实图像)相似的图像。所以,生成模型最底层的训练目标是:让生成图像的分布和给定图像的分布尽可能相似。

生成的过程,可以理解为从一个分布中采样的过程。

但是,我们无法得知,也无法直接计算给定图像的分布。为什么呢?因为如果能够得到给图图像的分布,那随机采样不就可以直接生成图像了,那还要做什么工作呢。事实上,我们这两个分布一个都求不出来。

所以,需要运用一些方法来等价这个训练目标:

  • 方法一:最大化似然,可以证明最大化似然就是在最小化两个分布的KL散度。

相关工作有:VAE、Diffusion、FLOW 以及它们的变体

  • 方法二:生成对抗训练,可以证明生成对抗训练就是在最小化两个分布的JS散度。

相关工作有:GAN 以及它的变体

拓展到文字领域,语言生成模型其目标也是:让生成文字的分布和给定文字的分布尽可能相似。不过,文字的分布是离散的。离散的分布之间的相似程度有一个很好衡量方法,那就是交叉熵损失。这就可以解释几乎所有语言模型的损失函数都是交叉熵损失的原因。

拓展到音频领域,音频分布和图像分布一样也是连续的,因此可以把图像领域的模型搬到音频领域来,这就是很多音频生成模型和图像生成模型原理一致的本质原因。

对于所有模态的生成任务,本质都是一样的,一切生成都可认为是分布采样的问题。包括:字体生成、排版生成、3D生成、视频生成、生物分子生成等等。

感叹一句,数学是理科之基不是吹的...

非常重要的结论!

生成模型的核心原理

总结一下五大类生成模型:VAE Diffusion FLOW GAN 语言模型

下面是我呕心沥血得到的结论,已死...

类型 核心原理 求解思路 具体求解方法
VAE 最大化似然/最小化KL散度 求解最大化似然的一种下界 A - B 设计了VAE模型,模型生成分布和真实分布的逼近程度为 A,模型的隐变量的分布和标准正太分布的逼近程度为 B,模型的训练目标为max A min B。
Diffusion 最大化似然/最小化KL散度 求解最大化似然的另一种下界 C - D + E 设计了Diffusion模型,D是常量不用管,C和E类似,E表示为前向过程的分布和逆向过程的分布的KL散度,而前向过程的分布的方差和均值确定,故模型训练目标使逆向过程接近前向过程的分布即可(均值 方差)
FLOW 最大化似然/最小化KL散度 求解最大化似然的等价形式 X X需要模型多步可逆,否则不等价,所以FLOW类方法都是设计一个巧妙的可逆的模型
GAN 生成对抗训练/最小化JS散度 最小化设计的LOSS A + B ,而这个LOSS等价于-2log2 + 2JS - A - B 就是0-1交叉熵损失,判别器目标是最小化这个交叉熵损失函数,生成器目标是最大化这个交叉熵损失函数(即最小化LOSS A + B)。
语言模型 最小化交叉熵 直接使用交叉熵损失函数 原理上任何模型都可以成为语言模型,只是效果好不好的问题,因为交叉熵损失函数可以直接算,也不用精巧的设计。 模型的好坏会影响交叉熵的最小值。模型越好交叉熵越小。

为什么语言模型可以简单地直接用交叉熵损失? 语言是离散分布,而图像、音频是连续分布。

为什么所有模态可通用?

图像、音频虽然是连续分布,但是我们可以将其变为离散分布,方法挺多的,不同模型用的不同,可以考虑单开一节。简单就直接取像素的整数值即可。

文字虽然是离散分布,但是embedding可以将其变为连续分布,套一个连续分布的生成模型,最后再近似转回到离散分布就OK了。比如 diffsion可以用于文字生成、item推荐。

An image caption

图仅为个人理解。

最大化似然=最小化KL散度?

↓ 这段话想了很久,表述是精准的,只是不太好理解。

假设对于任意一张给定的图,我们都能够计算模型(θ)产生它的概率。那么从数学上,我们可以证明:求解θ使“模型产生一组给定的图(真实的图)的概率的积”最大的过程,等同于使“模型产生图的分布(Pθ())接近于真实图像分布(Preal())”的过程。这就意味着,我们如果想要产生任意真实的图,只需要使模型产生一组给定的图(真实的图)的概率的积最大,证明过程如下所示:

An image caption

这就解释了:为什么在很多生成模型中,我们要最大化似然。

如何计算最大化似然?

直观上,最大化对数似然的下界,可以最大化对数似然。但是我们无法得到精确下界,而泛下界其实有很多种,所以不同的模型会给出不同的下界,比如VAE和Diffusion。他们模型的设计和损失函数的设计都是为了最大化这个下界。

FLOW不太一样,FLOW找到了似然的等价公式,而不是其下界,其训练目标直接是最大化似然的等价形式(比较顶)。然而这很难设计模型,因此效果不是很好。

VAE 的最大化下界

我们可以证明给定任意一个分布q(z|x),都可以求出对数似然关于该分布的下界,证明如下:

An image caption

将(1)和(6)联立,变形一下就有:

An image caption

而这个东西就是VAE推导出来的最大化似然的下界。

An image caption

那这个和VAE模型的训练目标有什么关系呢?解释如下:

An image caption

所以说,前半部分就是输入和输出的差异,这也是模型的第一个损失函数MSE;后半部分,我们假设了后延概率是正太分布,先验概率是标准正太分布,两者的差异就是第二个损失函数如下所示:

An image caption

至此,我们就能解释,为什么VAE要这样设计训练目标(损失函数)啦!

所以VAE不同于Autoencoders!!!Autoencoders是一个确定性模型,主要的作用的学习一个数据的隐性表达,因此可以用来压缩数据。而VAE是一个概率模型,它把深度模型和概率方法结合了起来,也因此取名Variational Autoencoder。它的主要作用是生成新的相似的数据而非学习一个低维的隐性表达(压缩)。

DDPM 的最大化下界

An image caption

这个下界分为三个部分:第一个部分和第三个部分处理相似,第二部分是个定值,所以我们只介绍第三部分的如何求解。 下界的三个部分放大来看,如下所示:

An image caption

其中蓝色部分是t-1时刻的分布,在数学上,可以求出该分布就是正态分布,且能得到其均值和方差:

An image caption
An image caption

那么,到目前为止,最大化下界就是最小化蓝色部分和其后面部分的KL散度。即,让这两个正太分布越接近越好。怎么让两个正太分布越接近越好呢?

由于其中一个正太分布(蓝色的部分)的均值和方差是已知的,DDPM选择了一个简单的方法,即让后面部分的均值越接近蓝色部分的均值(不考虑方差的事情,假设后面部分的方差固定),这样两分布就越接近。

An image caption

后面部分的均值又怎么求呢?直接让模型预测后面部分的均值,然后让这个预测的均值接近蓝色部分的均值(已知)。我们还可以对这个已知的均值化简一下,如下所示:

An image caption

放大来看就是:

An image caption

那么这个已知的均值被我们化简的很简单了,它就只包含了一个未知数,即添加的那一步噪声。那我们模型只取预测那个噪声就好啦,然后一切都解决了。

An image caption

这就解释了扩散模型的训练目标,但是直观上,这不就是加噪过程的逆公式吗。。。

不过,至此,我们就能更加深入理解Diffusion的损失函数设计啦!

FLOW:似然的等价形式

补充一则数学知识:

An image caption

其中的J表示雅各比矩阵,给定函数 f:(Rm x Rn ), 该函数的所有一阶偏导数组成的矩阵 J 称为 Jacobian 矩阵。若 m = n,可以定义关于方阵 J的行列式。

An image caption
An image caption

那么由变量变换定理,我们可以得到似然的等价形式:

An image caption

不过要想一步做到,基本上不可能,所以可以将其分解为多步可逆的操作:

An image caption

在训练过程中,我们只需要利用 f逆,而在推理过程中,我们使用 f 进行生成,因此对 f 约束为:f 网络是可逆的。这对网络结构要求比较严格,在实现时,通常要求 f 的输入输出是相同维度的来保证 f 的可逆性。这就是所有基于流模型的模型的设计思路。

生成对抗训练=最小化JS散度?

生成对抗训练,直观上可以理解为判别器和生成器训练,他的训练损失函数如下所示,其中D表示判别器,G表示生成器,x表示真实图像,z表示噪声向量:

An image caption

直观上理解这个公式:

  • 对于检测器D,它的目标是让x(真实图片)判断为1,由z生成的图片判断为0
  • 对于生成器G,它的目标是使得D将由z生成的图片判断为1

从数学上,我们可以证明这个训练目标就是最小化真实分布和生成分布之间的JS散度:

An image caption
An image caption
An image caption

如何进行生成对抗训练?

GAN的真实损失函数

现在我们只知道上面那个损失函数是正确的,按照它训练可以得到一个好的图像生成器,但是,这个损失函数根本算不出来啊,虽然其理论上可以简化为如下公式,但是样本空间是无穷大的,那么我们没办法获得它的真实期望。

An image caption

那么只能近似求解咯,也就是用部分真实和部分生成的样本去假装这个真实的分布,可以认为有点离散化的感觉。于是我们的训练目标就变成了一个0-1交叉熵损失了。

An image caption

至此,生成对抗训练的损失函数就是一个简单的分类交叉熵损失。不过只是交替训练效果最好。

注意判别器目标是最小化这个交叉熵损失函数,生成器目标是最大化这个交叉熵损失函数。

GAN的本质问题

一个问题是,GAN设计损失函数并不完全等于两倍的JS散度,也就是前面有-2log2这个部分。

我们知道,当损失函数一直为0时,其实我们无法训练模型,而当两个分布不重叠时,JS散度取log2,从而这个损失函数取0。有两种情况会导致两个分布不重叠:

  • 其一:生成器太辣鸡了,生成图的分布一直和真实的图的分布重叠不了。
  • 其二:判别器太强大了,甚至过拟合,硬是能把两个分布完全分开。

以上两种情况会导致GAN很难训练,问题一可以加正则化方法或者减少模型参数让他变弱,问题二可以加一点噪声让两个分布重叠。但是这两个解决方案只能缓解问题,本质无法改变。

An image caption