(5)AIGC组成原理(上)
开篇
大家好,我是aaronxic。前面几篇我们已经感受了transformer是如何应用在LLM和多模态领域的,从这一篇开始我们把目光转向AIGC,看看AIGC任务都是由哪些部件组装而成的。
AIGC (Artificial Intelligence Generative Content)即人工智能生成内容,这里强调的是GC部分,也就是decoder部分。
- 上一篇 (4)多模态的大一统之路 侧重的是encoder部分,包括对Image和Video的编码。对decoder的生成主要聚焦在生成text生成上
- 本篇《AIGC组成原理(上)》将介绍常见的4大类生成算法,包括了VAE、GAN、FlowModel和Diffusion Model。同时,还会介绍IS(Inception Score)和FID(Frechet Inception Distance)两种生成图片常见评价指标。
- 下一篇《AIGC组成原理(下)》将介绍具体的Image生成、Video生成、Audio生成和3D生成算法
PS: 长文预警,本篇约12000字,关注&收藏后电脑上阅读体验更加哦~ (^_^)
提纲如下,共2个章节
- 首先介绍了生成模型的本质目的,就是为了建模p(x)
分布。
- 首先是最朴素的极大似然估计,虽然简单,但是要求有明确的参数化分布形式,在实际中往往不可得
- 接着介绍4种隐变量模型,包括VAE,GAN,Flow Model和Diffusion Model。本质上用p(x)=\int p(x|z) p(z) \text{d}z 来近似
- VAE模型。尝试提高p(z) 采样效率,尝试最小化\text{KL}(q_\theta(z|x)||p(z)) ,最终得到了正则项和重建误差项
- GAN模型。尝试对MSE的损失函数做进一步拓展,引入判别模型D(x', x) 来隐式学习度量方法
- Flow Model模型。强行让f 函数可逆,满足x 和z 的一一映射,以RevNet为例子介绍Flow Model具体使用方式
- Diffusion Model (DDPM)。将VAE扩展到了多步,有复杂的数学推导,但是本质上跟VAE是相似的
- DDPM的score function。换一种角度理解DDPM,发现可以用网络s\theta(x_t, t) s\theta(x_t, t) 来预测\nabla{x_t}\log p(x_t)
- DDIM。尝试对DDPM做采样加速,将DDPM变成了确定性的过程
- classifier-guided。使用classifier-guided技术,首次把DDPM和DDIM的IS和FID指标拉高到GAN齐平。在推理阶段,DDPM可以直接分析p(x_t|x_{t+1}, y) ;而对于DDIM,由于是个确定性过程,因此退化成分析p(x_t|y)
- classifier-free。为了省去classifier-guided的梯度计算过程,classifier-free在训练中混合训练有condition和无condition的模型,使得在推理阶段无需求解梯度,在提高保真度的同时计算效率也很高
- 接着介绍了图片生成常见的两种指标
- IS(Inception Score)指标提供了两种理解角度。IS本身有很强的先验,认为符合ImageNet的分布才是真实分布
- FID(Frechet Inception Distance) 指标,衡量两个数据集的距离,更科学一点
从生成模型谈起
假设我们有一批大小为N 的真实图片数据集合,S_x={x_1, x_2, \cdots, x_N}
- 如果有一个完美的分布 p(x) 能生成集合S_x 中的元素,就意味着要求每次采样出来的x' \sim p(x) 都满足x' \in S_x 。
- 当集合元素N 比较小的时候,p(x) 可以强行背下来即可;但是当N 变得非常大的时候,完美分布p(x) 就几乎不可能获取了。
而AIGC的任务就是逼近这个完美分布p(x) ,这里的x 可以是Image,可以是Video,可以是Audio或者3D模型
那具体如何逼近这个完美分布p(x) 呢?各类方法各显神通,下面我们就来逐个来看
极大似然估计
估计分布 p(x) 有个最直接的方法,就是极大似然估计。先假设 p(x) 的形式为 p_\theta(x) ,然后待定其中的参数 \theta 。例如我们假设$x$来自多元高斯分布 \mathcal{N}(\mu, \Sigma) ,即 x \sim \mathcal{N}(\mu, \Sigma) ,其中高斯分布的维度和图片的像素个数一致。于是这里的待定参数就是 \theta=(\mu, \Sigma) ,此时似然估计函数为
L_\theta(S_x)=p(S_x;\theta)=\prod_{i=1}^N p(x_i;\theta)
做最大似然估计,用梯度下降或者公式推导求解出最佳参数 \hat{\theta}
(\hat{\mu}, \hat{\Sigma})=\hat{\theta}=\argmax_\theta L_\theta(S_x)=\argmin_\theta(-\sum_{i=1}^N \ln p(x_i;\theta))
这样就求得了 p(x) 的分布为 \mathcal{N}(\hat{\mu}, \hat{\Sigma})
上述方法简单直观,但是弊端也很明显:
- p(x) 形式未知。需要丰富的领域知识才能笃定 p(x) 就是某个形式,其实对于复杂问题来说只有上帝才知道分布的参数化表达式是啥
- 参数量 \theta 的空间太大。多元高斯分布的维度跟图片像素数一样大,例如ImageNet是 \mathbb{R}^{3 \times 224 \times 224} 维度,那么意味着是150528元高斯分布,那得需要多少海量的数据才能估计得准确呀
隐变量估计
为了解决上述两个问题,更加广泛使用的方式是隐变量估计法,目前生成模型主流的4大类方法本质上都是生成模型,如下所示。原图出处
在介绍上述4种方法之前,我们先深入了解一下隐变量模型是什么。
隐变量模型顾名思义,就是引入隐变量 z ,期望从简单的分布 p(z) 出发,用积分公式来间接求出复杂的 p(x)
p(x)=\int p(x|z) p(z) \text{d}z
这里值得注意的是
- 简单满足两个性质。
- p(z) 分布表达式简单,例如是普通的多元高斯分布
- z 自由度低,例如对于多元高斯分布,维度为 d ,其中 d \ll 3 \times 224 \times 224
- p(x|z) 可以是个确定性的过程 p_\theta(x|z) ,即 x=f(z) , f 用神经网络来表示
- 有了万能拟合函数 f
,那么从简单分布 p(z)
生成任意分布 p(x)
过程为
- Step1: 假设想得到 p(x=x') 的概率,那么就先研究 f 找到所有 z 使得 x'=f(z)
- Step2: 假设 z 的解集合为 {z_1, z_2, \cdots, z_M} ,则把这些 z 出现的概率全部加起来就是 x' 出现的概率,即可以得到 p(x=x')=\sum_{i=1}^Mp(z=z_i)
但是要找到Step2里面 z 的解集合是很难的,所以虽然 p(z) 很简单, f 是个确定过程,但由于 f 不一定可逆, p(x) 仍然很难直接算出表达式。
我们能做的是数值模拟的方式采样出 x' \sim p(x) ,常用的为蒙特卡洛方法
- 首先依 p(z) 的分布采样 K 次 z ,得到数组 T_z=[z_1, z_2, \cdots, z_K] ,其中 z_i \sim p(z)
- 根据 x=f(z) 计算得到数组 T_x=[x_1, x_2, \cdots, x_K]
- 注意如果 p(z_i) 概率更高,那么 z_i 出现在 T_z 的次数会越多,相应的 x_i 出现在 T_x 的概率就会高
- 只需要简单对 T_x 取均值即可得到本次采样最终的 x'=\frac{1}{K}\sum_{i=1}^Kx_i
蒙特卡洛方法虽然简单,但是也有2个可改进方向
- 提高采样效率。这里的 K 可能需要非常大才能得到对应满意的结果,也就是生成一个 x' 需要很多次 z 的采样。因此一种思路是提高 z 的采样效率,最好采样一次就能完成任务 (VAE方向)
- 损失误差不用均方误差MSE。在实际网络训练中,上述蒙特卡洛采样过程,每次得到的 x' 会启发式地和真实图片 x 做MSE。但没有证据表明MSE就是最优度量,因此另外一种思路是用神经网络 D(x, x') 来隐式学这个度量方式 (GAN方向)
VAE
观察隐变量的积分式
p(x)=\int p(x|z) p(z) \text{d}z
如何提高 z 的采样效率呢?一种思路是用 p(z|x) 来估计 p(z) ,原因是有了 x 的信息, z 怎么着都应该变得确定一点吧。这里研究的变量是 z ,因此 p(z) 是先验分布, p(z|x) 是后验分布。
但即便如此,无中生有出 p(z|x) 会陷入鸡生蛋和蛋生鸡的窘境,我们需要一个具体可优化模型来逼近 p(z|x) ,于是引入新的概率分布 q_\theta(z|x) 。思路逐渐清晰了
- Step1:先想办法构造一个新的分布 q\theta(z|x) q\theta(z|x) ,使得 z' \sim q\theta(z|x) z' \sim q\theta(z|x)
- Step2:然后不断优化 q_\theta(z|x) 靠近 p(z|x) ,使得最终近似满足 z'\sim p(z|x)
引入的 q\theta(z|x) q\theta(z|x) 是一系列的分布家族,并且需要在里面做优化,选择最合适的 q{\theta^*}(z|x) q{\theta^*}(z|x) 分布,这个过程就是变分。
下面我们用KL衡量一下这两个分布的差距
\begin{align} \text{KL}(q_\theta(z|x) ||p(z|x)) &= \int q_\theta(z|x)\ln \frac{q_\theta(z|x)}{p(z|x)} \text{d}z \\ &= \mathbb{E}_{z\sim q_\theta(z|x)}[\ln q_\theta(z|x) - \ln p(z|x)]\\ &= \mathbb{E}_{z\sim q_\theta(z|x)}[\ln q_\theta(z|x) - \ln \frac{p(x|z)p(z)}{p(x)}]\\ &= \mathbb{E}_{z\sim q_\theta(z|x)}[\ln q_\theta(z|x) - \ln p(x|z) - \ln p(z) + \ln p(x)]\\ &=\text{KL}(q_\theta(z|x)||p(z))-\mathbb{E}_{z\sim q_\theta(z|x)}\ln p(x|z) + \ln p(x) \end{align}
可以看到,通过变分我们绕过了虚无缥缈的 p(z|x) ,留下的3项都是可以分析的对象。
下面我们逐项分析:
- 明确目标是希望左侧的KL距离越来越小,并且要重点关注 q_\theta(z|x) 要怎么变才能逼近 p(z|x)
- 右边第一项 \text{KL}(q_\theta(z|x)||p(z)) ,希望尽可能小,也就是新引入的采样过程得到的 z' 不能离原来的标准多元高斯分布假设 p(z) 太远。我们是希望 z' 的方差变小,而不是完全变个样。这个不就是正则项要尽可能小嘛
- 右边第二项 -\mathbb{E}{z\sim q\theta(z|x)}\ln p(x|z) -\mathbb{E}{z\sim q\theta(z|x)}\ln p(x|z) -\mathbb{E}{z\sim q\theta(z|x)}\ln p(x|z) ,希望尽可能小,也就是 \mathbb{E}{z\sim q\theta(z|x)}\ln p(x|z) \mathbb{E}{z\sim q\theta(z|x)}\ln p(x|z) \mathbb{E}{z\sim q\theta(z|x)}\ln p(x|z) 要尽可能大,含义就是每张图的似然 \ln p(x|z) 在所有 z 采样中要尽可能解释观测数据 $x$,这个不就是重建误差要尽可能小嘛
- 右边第三项 \ln p(x) ,是个跟 q\theta(z|x) q\theta(z|x) 没啥关系的常数,不随 q\theta(z|x) q\theta(z|x) 变化而变化,忽略
上式也常常写成如下形式
\begin{align} \ln p(x) &= \text{KL}(q_\theta(z|x) ||p(z|x)) -\text{KL}(q_\theta(z|x)||p(z)) + \mathbb{E}_{z\sim q_\theta(z|x)}\ln p(x|z)\\ &\ge -\text{KL}(q_\theta(z|x)||p(z)) + \mathbb{E}_{z\sim q_\theta(z|x)}\ln p(x|z) \\ &= \text{Variational Lower Bound} \end{align}
要最大化$p(x)$,只需要不断提高VLB(Variational Lower Bound)即可,即最大化VLB
由上我们知道了第一项就是正则项,第二项就是重建误差,整个VAE的网络呼之欲出,魔改苏老师的图,如下所示
- q_\theta(z|x)
过程是采样过程。而神经网络g是个确定性过程,本身没有随机性,因此为了让网络参数可学习,需要引入重参数化技巧。拿图中各分量独立的多元高斯变量举例
- g过程直接预测每个维度的均值 \mu_i 和方差 \sigma_i ,然后叠加随机数发生器 \epsilon_i \sim \mathcal{N}(0, 1) ,得到采样结果 z'_i = \sigma_i \cdot \epsilon_i+ \mu_i
- 每个维度 i 都操作完之后得到 z'=[z'1, z'2, \cdots, z'_d] z'=[z'1, z'2, \cdots, z'_d] z'=[z'1, z'2, \cdots, z'_d]
- 所有 \mu_i 组成 \mu ,所有 \sigma_i 组成 \Sigma ,则 z' \sim \mathcal{N}(\mu, \Sigma)
- p_\theta(x|z) 过程是个确定性过程,当 z' 被采样出来之后,直接调用decoder网络就能得到重建的 \hat{X}
对VAE网络有了认识,我们再回到VAE网络的loss上来,包含两项:
- 最小化正则项。从 \text{KL}(q\theta(z|x)||p(z)) \text{KL}(q\theta(z|x)||p(z)) 转为 \text{KL}(\mathcal{N}(\mu,\Sigma)||\mathcal{N}(0, I)) ,有闭式解,即最小化 \sum{j=1}^d\frac{1}{2}(-\ln \sigma_j^2 + \sigma_j^2 + \mu_j^2 -1) \sum{j=1}^d\frac{1}{2}(-\ln \sigma_j^2 + \sigma_j^2 + \mu_j^2 -1)
- 最小化重建误差项。 \mathbb{E}{z\sim q\theta(z|x)}\ln p(x|z) \mathbb{E}{z\sim q\theta(z|x)}\ln p(x|z) \mathbb{E}{z\sim q\theta(z|x)}\ln p(x|z) 可以转换为要求 x_i 和 \hat{x}i \hat{x}i 的MSE的值尽可能小,即最小化 \sum{i=1}^N||x_i - \hat{x}^i||^2_2 \sum{i=1}^N||x_i - \hat{x}^i||^2_2
最终VAE网络的loss如下
\sum_{i=1}^N (\frac{1}{2}\sum_{j=1}^d(\sigma_{i,j}^2 +\ln \frac{1}{\sigma_{i,j}^2} + \mu_{i,j}^2 -1) + ||x_i - \hat{x}^i||^2_2)
模型收敛之后
- 把encoder网络丢弃
- 每次按标准多元高斯分布采样$z$,然后经过decoder网络输出 \hat{x} ,完成一次采样
GAN
让我们重新回到梦开始的地方,再看看隐变量模型
p(x)=\int p(x|z) p(z) \text{d}z
前面说到VAE的思路是提高 p(z) 采样效率,参数化后验分布 q\theta(z|x) q\theta(z|x) ,引入数据依赖直接得到均值 \mu 和方差 \Sigma ,使得 q\theta(z|x)=\mathcal{N}(\mu, \Sigma) q\theta(z|x)=\mathcal{N}(\mu, \Sigma)
而原始GAN的思路是保留 p(z) 是固定的标准多元高斯分布,额外引入新网络 D(x', x) 对生成的 x' 和真实的 x 做分类,而不是像VAE一样用固定的MSE损失函数
GAN的数学化表达如下,公式直观,但是背后蕴藏了非常多玄机,对GAN的性质和优化感兴趣的建议阅读这篇关于WGAN的文章
-\mathbb{E}_{x\sim P_r}[\log D(x)]-\mathbb{E}_{x\sim P_g}[\log(1- D(x))]
Flow Model
我们接着介绍第三种生成模型Flow Model,还是从隐变量模型说
p(x)=\int p(x|z) p(z) \text{d}z
前面介绍了如何用神经网络 f 来表示 p_\theta(x|z) 来建立 z 和 X 的关系,方法如下
- Step1: 假设想得到 p(x=x') 的概率,那么就先研究 f 找到所有 z 使得 x'=f(z)
- Step2: 假设 z 的解集合为 {z_1, z_2, \cdots, z_M} ,则把这些 z 出现的概率全部加起来就是 x' 出现的概率,即可以得到 p(x=x')=\sum_{i=1}^Mp(z=z_i)
但我们知道,想得到Step2里面 z 的解集合是很难的,所以虽然 p(z) 很简单, f 是个确定过程,但由于 f 不一定可逆, p(x) 仍然很难直接算出表达式。于是退而求其次,不求 p(x) 的表达式了,只求蒙特卡洛的方式能采样出 x' \sim p(x) 就好
但如果,我们就是想硬上求出表达式呢,其实也可以,只是需要满足
- f 函数是可逆的,即知道了 x=f(z) ,那么容易推导出来 z =f^{-1}(x)
- 因此 f 是一一映射的,同时 x 和 z 要求是维度一样的,如果 x \in \mathbb{R}^{D} 那么 z \in \mathbb{R}^{D}
- 既然 f 是一一映射的,也用不着积分了,直接变量替换 z=f^{-1}(x) \sim \mathcal{N}(0, I)
变量替换后概率密度如下
p(x)=\frac{1}{(2\pi)^{D/2}}\exp(-\frac{1}{2}||f^{-1}(x)||^2)\bigg |\det[\frac{\partial {f^{-1}}}{\partial x}]\bigg|
可见除了要求 f 可逆,还要求逆函数 f^{-1}(x) 的行列式计算也要简单
贯彻了flow model理念的代表作有RevNet (Reversible Network),可逆网络,如下所示
- 输入是 x ,输出是 y
- 把 x 分成两部分 x_1 和 x_2 ,把 y 也分成两部分 y_1 和 y_2
- 输入和输出tensor shape一样的函数 \mathcal{F} 和 \mathcal{G}
那么可以计算前馈和反传
主要这个跟省显存的技术checkpointing不一样
- checkpoint是通过更浅层的输入重计算当前层输入
- RevNet是通过当前层的输出直接算出当前层的输入
有了当前层的输入,接着就可以正常求梯度了。完整的梯度回传公式如下
Diffusion Model (DDPM)
最后我们看看近几年爆红的以DDPM为代表的Diffusion Model,继续回到隐变量模型
p(x)=\int p(x|z) p(z) \text{d}z
回想VAE的思路是提高$p(z)$采样效率
- encoder。用参数化的后验分布模型 q\theta(z|x) q\theta(z|x) ,直接预测均值 \mu 和方差 \Sigma ,使得 q\theta(z|x)=\mathcal{N}(\mu, \Sigma) q\theta(z|x)=\mathcal{N}(\mu, \Sigma)
- decoder。采样得到 z 之后,经过参数化的 p_\theta(x|z) 生成最后的 \hat{x}
如果 q_\theta(z|x) 不是一步生成的,而是经过 T 步会怎么样呢,即encoder为
q_\theta(z|x)=q_\theta(z|x_{T-1})\cdot q_\theta(x_{T-1}|x_{T-2})\cdots q_\theta(x_{t}|x_{t-1}) \cdots q_\theta(x_2|x_1) \cdot q_\theta(x_1|x)
同理decoder可以变成
p_\theta(x|z)=p_\theta(x|x_1)\cdot p_\theta(x_1|x_2)\cdots p_\theta(x_{t-1}|x_t) \cdots p_\theta(x_{T-2}|x_{T-1})\cdot p_\theta(x_{T-1}|z)
如下所示,这个就是diffusion model的思想,但跟VAE也有很大不同
(PS: 符号变换一下, x 变成了 x_0 , z 变成了 x_T )
- 从右往左的encoder是无参数的 q(x_t|x_{t-1}) 。不像VAE是带超参数的,这是个人为定义的过程,从原始清晰图 x_0 开始,每次转换成新的高斯噪声,逐渐变成标准多元高斯变量 x_T 。
- 从左往右的decoder是带参数的 p\theta(x{t-1}|x_t) p\theta(x{t-1}|x_t) p\theta(x{t-1}|x_t) 。不是像VAE一样直接预测 \hat{x} ,而是预测高斯噪声,并且会减去这个高斯噪声得到更清晰的图片
- 另外中间隐变量 x_T 的维度变成了跟原始图片 x_0 一样大
encoder过程
首先定义递增的常量序列 \beta_t ,满足 0<\beta_1 \lt \beta_2 \lt \cdots \lt \beta_T<1
定义观测原图为随机变量 x_0 ,然后定义从随机变量 x_{t-1} 到随机变量 x_t 的分布关系为
\begin{align}q(x_t|x_{t-1})=\mathcal{N}(x_t;\sqrt{1-\beta_t}x_{t-1}, \beta_t )\end{align}
即 x_t 是均值 \sqrt{1-\beta_t}x_{t-1} 且方差为 \beta_t 的高斯分布,用类似重参数分解可以得到
\begin{align}x_t = \sqrt{1-\beta_t}x_{t-1} + \sqrt{\beta_t} \epsilon_{t-1}, \ \epsilon_i \sim \mathcal{N}(0, 1)\end{align}
对于公式(2)有以下一些解释
- x{t-1} x{t-1} 和 \epsilon{t-1} \epsilon{t-1} 前面的两个系数平方和等于1
- \beta_t 单调递增且 \beta_t \in (0, 1) ,则可以保证 t=0 时候方差几乎为0, t=T 时方差几乎为1
如果定义
- \alpha_t=1-\beta_t 。为了书写方便
- \bar{\alpha}t=\prod{i=1}^t \alpha_i \bar{\alpha}t=\prod{i=1}^t \alpha_i \bar{\alpha}t=\prod{i=1}^t \alpha_i 。为了书写方便
- \bar{\epsilon}_k \sim \mathcal{N}(0, 1) 。代表 k 个高斯分布合并之后的新高斯分布
那么递推展开可以得到
\begin{align}x_t&=\sqrt{\alpha_t} x_{t-1} + \sqrt{1-\alpha_t} \epsilon_{t-1} \\ &=\sqrt{\alpha_t \alpha_{t-1}} x_{t-2} + \sqrt{1-\alpha_t \alpha_{t-1}} \bar{\epsilon}_2 \\&= \cdots \\&=\sqrt{\bar{\alpha_t}}x_0 +\sqrt{1-\bar{\alpha_t}}\bar{\epsilon}_t\end{align}
注意
- 这里用了方差的性质,即两个高斯分布的和还是高斯分布,并且新方差等于这两个高斯分布的方差
- \bar{\epsilon}_k 是 k 个高斯分布合并之后的新高斯分布
- x_0 和 \bar{\epsilon}_t 前面两个系数的平方和仍然是1
观察公式(6)里的$x_t$可以发现
- 随着 t \rightarrow T , \sqrt{\bar{\alpha_t}} \rightarrow 0 且 \sqrt{1-\bar{\alpha_t}} \rightarrow 1 ,因此 x_t \rightarrow \mathcal{N}(0, 1) ,逐渐变成标准高斯分布,极端情况下 x_T =\mathcal{N}(0, 1)
- 不仅 q(x_t|x{t-1})=\mathcal{N}(\sqrt{1-\beta_t}x{t-1}, \beta_t ) q(x_t|x{t-1})=\mathcal{N}(\sqrt{1-\beta_t}x{t-1}, \beta_t ) q(x_t|x{t-1})=\mathcal{N}(\sqrt{1-\beta_t}x{t-1}, \beta_t ) 可以直接计算,并且 q(x_t|x_0)=\mathcal{N}(\sqrt{\bar{\alpha_t}}x_0 , 1-\bar{\alpha_t}) 也可以直接计算
- 整个encoder过程的是完全透明的,可以高效的计算中间任意分布 q(x_t|x_0) 的方式
优化目标
有了encoder过程后,接下来寻找优化目标。我们有两种推导方式
- 方法1:最小化 D{\text{KL}}(q(x{1:T}|x_0)||p\theta(x{1:T}|x_0)) D{\text{KL}}(q(x{1:T}|x_0)||p\theta(x{1:T}|x_0)) D{\text{KL}}(q(x{1:T}|x_0)||p\theta(x{1:T}|x_0)) D{\text{KL}}(q(x{1:T}|x_0)||p\theta(x{1:T}|x_0)) D{\text{KL}}(q(x{1:T}|x_0)||p\theta(x{1:T}|x_0)) (跟前面VAE一样)
- 方法2:最小化CE损失 -\mathbb{E}{q(x_0)}\log p\theta(x_0) -\mathbb{E}{q(x_0)}\log p\theta(x_0) -\mathbb{E}{q(x_0)}\log p\theta(x_0)
殊途同归,发现都是要最小化 L_{t-1}
L_{t-1}=\text{KL}(q(x_{t-1}|x_t, x_0) || p_\theta(x_{t-1}|x_t))
- q(x_{t-1}|x_t, x_0) 可以用贝叶斯公式求得
- p\theta(x{t-1}|x_t) p\theta(x{t-1}|x_t) p\theta(x{t-1}|x_t) 是 q(x_{t-1}|x_t) 的参数化建模,假设也符合高斯分布,只需关注均值和方差即可
分析 \mathbf{q(x_{t-1}|x_t, x_0)}
使用贝叶斯公式
\begin{align} q(x_{t-1}|x_t, x_0) &= q(x_t|x_{t-1},x_0) \frac{q(x_{t-1}|x_0)}{q(x_t|x_0)} \\ &= q(x_t|x_{t-1}) \frac{q(x_{t-1}|x_0)}{q(x_t|x_0)} \end{align}
惊喜地发现每个 q(\cdot) 代表的是高斯函数的密度函数,因此可以带入得到 q(x{t-1}|x_t, x_0) q(x{t-1}|x_t, x_0) 的密度函数,并且也是高斯分布。此时是可以用待定系数的方式 推导求出 q(x{t-1}|x_t, x_0) q(x{t-1}|x_t, x_0) 的均值 \mu_t(x_t, x_0) 和方差 \sigma_t^2(x_t, x_0) 的,如下所示
\begin{align}\mu_t(x_t,x_0)&=\frac{\sqrt{\alpha_t}(1-\bar{\alpha}_{t-1})}{1-\bar{\alpha}_t}x_t+\frac{\sqrt{\bar{\alpha}_{t-1}}(1-\alpha_t)}{1-\bar{\alpha}_t}x_0\\\sigma_t^2(x_t, x_0)&=\frac{1-\bar{\alpha}_{t-1}}{1-\bar{\alpha}_t} \cdot \beta_t\end{align}
把式中的 x_0 代换掉,可以得
\begin{align}\mu_t(x_t,x_0)&=\frac{1}{\sqrt{\alpha_t}} (x_t-\frac{1-\alpha_t}{\sqrt{1-\bar{\alpha}_t}} \bar{\epsilon}_t)\\\sigma_t^2(x_t, x_0)&=\frac{1-\bar{\alpha}_{t-1}}{1-\bar{\alpha}_t} \cdot \beta_t\end{align}
观察分析方差公式 \sigma_t^2(x_t, x_0) ,其实有好几种选择
- 选择1: \bar{\alpha}{t-1} \bar{\alpha}{t-1} 和 \bar{\alpha}t \bar{\alpha}t 是通过预先设置 \beta_t 直接计算而来,运算结果是常量
- 选择2:DDPM里面进一步发现可以简化成 \sigma_t^2(x_t, x_0)=\beta_t
- 选择3:Improved DDPM里面发现也可以设置成可学
这里我们使用第2种选择 \sigma_t^2(x_t, x_0)=\beta_t ,因此
\begin{align}q(x_{t-1}|x_t, x_0)=\mathcal{N}(x_{t-1};\mu_t(x_t, x_0), \beta_t)\end{align}
分析 \mathbf{p\theta(x{t-1}|x_t)} \mathbf{p\theta(x{t-1}|x_t)} \mathbf{p\theta(x{t-1}|x_t)}
由于已经假设 p\theta(x{t-1}|x_t) p\theta(x{t-1}|x_t) p\theta(x{t-1}|x_t) 是高斯分布且满足
\begin{align}p_\theta(x_{t-1}|x_t)=\mathcal{N}(x_{t-1}; \mu_\theta(x_t, t), \beta_t)\end{align}
那么当我们计算两个高斯分布的KL散度,利用现成结论公式可以得到
\begin{align}L_{t-1}&=\text{KL}(\mathcal{N}(x_{t-1};\mu_t(x_t, x_0), \beta_t)||\mathcal{N}(x_{t-1}; \mu_\theta(x_t, t), \beta_t))\\&\propto||\mu_t(x_t, x_0)-\mu_\theta(x_t, t)||^2\end{align}
DDPM的贡献点之一,就是发现与其让网络输出 $\mu\theta(x_t, t)$预测$\mu_t(x_t, x_0)$ ,不如让网络输出 \epsilon\theta(x_t,t) \epsilon\theta(x_t,t) 预测 \bar{\epsilon}t \bar{\epsilon}t 。 \mu\theta(x_t, t) \mu\theta(x_t, t) 和 \epsilon_\theta(x_t,t) 关系如下
\begin{align}\mu_\theta(x_t, t)= \frac{1}{\sqrt{\alpha_t}} (x_t-\frac{1-\alpha_t}{\sqrt{1-\bar{\alpha}_t}} \epsilon_\theta(x_t,t))\end{align}
于是终于得到了最终的Loss表达式
\begin{align}L_{t-1} &\propto ||\bar{\epsilon}_t-\epsilon_\theta(x_t,t)||^2 \\&= ||\bar{\epsilon}_t-\epsilon_\theta(\sqrt{\bar{\alpha_t}}x_0 +\sqrt{1-\bar{\alpha_t}}\bar{\epsilon}_t,t)||^2\end{align}
于是终于得到了最终的Loss表达式
\begin{align}L_{t-1} &\propto ||\bar{\epsilon}_t-\epsilon_\theta(x_t,t)||^2 \\&= ||\bar{\epsilon}_t-\epsilon_\theta(\sqrt{\bar{\alpha_t}}x_0 +\sqrt{1-\bar{\alpha_t}}\bar{\epsilon}_t,t)||^2\end{align}
这里 \epsilon\theta(\sqrt{\bar{\alpha_t}}x_0 +\sqrt{1-\bar{\alpha_t}}\bar{\epsilon}t,t) \epsilon\theta(\sqrt{\bar{\alpha_t}}x_0 +\sqrt{1-\bar{\alpha_t}}\bar{\epsilon}t,t) \epsilon\theta(\sqrt{\bar{\alpha_t}}x_0 +\sqrt{1-\bar{\alpha_t}}\bar{\epsilon}t,t) 是个U-Net网络,并且时间步 t 需要做embedding灌入网络
训练&推理过程
因此训练方式呼之欲出,引用DDPM的原始paper伪代码
- 训练的时候只从 T 步里面随机抽取一步来算,这归功于 x_t 只需要 x_0 就能直接算出的良好性质
- line2-3: 从数据集随机抽取一张图片 x_0 ,同时随机选择一个时间步 t
- line4: 从标准高斯分布里面采样一个值,当做 x_t 表达式中由 t 个高斯分布合并的新分布 \bar{\epsilon}_t 的采样结果
- line5: 按照上面MSE的loss的来求梯度,并且做梯度更新
相应的推理过程如下所示
- 跟VAE一样,训练完就扔掉encoder,然后从标准高斯分布开始采样,然后经过 T 步递推产生 x_0
- line1:从 x_T 开始,从标准高斯分布采样
- line2-5, t
从 T
不断递减,直到 t=1
- 每一步decoder输入为 t 和 x_t ,神经网络先预测出噪声 \epsilon_\theta(x_t, t)
- x{t-1} x{t-1} 的均值按 \mu\theta(x_t, t) \mu\theta(x_t, t) 的公式计算出
- x_{t-1} 的方差 \sigma_t 可以按前面的 \sigma_t(x_t, x_0) 公式计算出来。直接用 \sigma_t^2=\beta_t 效果也不错,总之不需要神经网络预测
- 然后从高斯分布 \mathcal{N}(\mu\theta(x_t, t),\sigma^2_t) \mathcal{N}(\mu\theta(x_t, t),\sigma^2_t) 里面采出样本作为 x{t-1} x{t-1}
- 这里容易造成困惑的是生成过程每一步为什么还需要采样 z ,直接高斯分布的均值不行吗?个人理解这类似于ChatGPT里面推理的top-p核采样 (忘记的同学可以参考(3)ChatBot是怎么炼成的? ,需要引入一定的随机性,最后的效果反而更好
DDPM推导非常多,我们梳理一下核心逻辑
- 首先建模encoder过程为清晰图 x_0 到标准高斯分布 x_T 的扩散过程,相应的decoder过程为标准高斯分布 x_T 到清晰图 x_0 的采样过程。我们最后需要的是decoder过程。
- 定义单调递增的序列 \beta_t ,并定义 q(x_t|x_{t-1}) 的递推表达式
- 利用递推式可以求出encoder的每一步 x_t 的分布 q(x_t|x_0)
- 利用贝叶斯公式可以求出分布 q(x{t-1}|x_t, x_0) q(x{t-1}|x_t, x_0) ,并且满足 \mathcal{N}(x{t-1};\mu_t(x_t, x_0),\sigma_t^2(x_t, x_0)) \mathcal{N}(x{t-1};\mu_t(x_t, x_0),\sigma_t^2(x_t, x_0))
- 变分分析得出最终的优化loss目标为 L{t-1}=\text{KL}(q(x{t-1}|x_t, x_0) || p\theta(x{t-1}|x_t)) L{t-1}=\text{KL}(q(x{t-1}|x_t, x_0) || p\theta(x{t-1}|x_t)) L{t-1}=\text{KL}(q(x{t-1}|x_t, x_0) || p\theta(x{t-1}|x_t)) L{t-1}=\text{KL}(q(x{t-1}|x_t, x_0) || p\theta(x{t-1}|x_t)) L{t-1}=\text{KL}(q(x{t-1}|x_t, x_0) || p\theta(x{t-1}|x_t))
- 设置 p\theta(x{t-1}|x_t) p\theta(x{t-1}|x_t) p\theta(x{t-1}|x_t) 为高斯分布,并且满足 \mathcal{N}(x{t-1}; \mu\theta(x_t, t), \beta_t) \mathcal{N}(x{t-1}; \mu\theta(x_t, t), \beta_t) \mathcal{N}(x{t-1}; \mu\theta(x_t, t), \beta_t)
- 带入 L{t-1} L{t-1} 求解,化简表达式,最终发现网络预测噪声 \epsilon\theta(x_t,t) \epsilon\theta(x_t,t) 来逼近 \bar{\epsilon}_t 即可
从Score Function理解DDPM
energy function
对于任意分布 p(\textbf{x}): \mathbb{R}^{D \rightarrow 1} ,没法直接以 D 维输入和1维输出的神经网络拟合,原因是要求
\int p(\textbf{x}) dx=1
但是如果做了如下变换后,发现 f_\theta(\textbf{x}) 几乎没有任何约束了
p(\textbf{x})=\frac{1}{Z_\theta}e^{-f_\theta(\textbf{x})}
此时虽然引入了归一化分母 Z_\theta ,但是如果我们取对数并且对 \textbf{x} 求导,则
\begin{align} \nabla_\textbf{x}\log p(\textbf{x}) &= \nabla_\textbf{x}\log (\frac{1}{Z_\theta}e^{-f_\theta(\textbf{x})}) \\ &= \nabla_\textbf{x}\log \frac{1}{Z_\theta} + \nabla_\textbf{x}\log (e^{-f_\theta(\textbf{x})})\\ &= -\nabla_\textbf{x}f_\theta(\textbf{x}) \end{align}
惊奇地发现 Z\theta Z\theta 不见了,这里的 f\theta(\textbf{x}) f\theta(\textbf{x}) 就是energy function,是个自由函数
score function
进一步观察,发现 \nabla_\textbf{x}\log p(\textbf{x}) 是让 p(\textbf{x}) 概率最大化的前进方向,是个向量场,向量指向最大值的前进方向
此时如果定义 \mathbf{s}\theta(\textbf{x}) \in \mathbb{R}^{D \rightarrow D} \mathbf{s}\theta(\textbf{x}) \in \mathbb{R}^{D \rightarrow D} ,并且要求 \mathbf{s}\theta(\textbf{x}) \mathbf{s}\theta(\textbf{x}) 去直接拟合 \nabla_\textbf{x}\log p(\textbf{x}) ,即最小化
\mathbb{E}_{p(\textbf{x})}[||\textbf{s}_\theta(\mathbf{x})-\nabla_\textbf{x}\log p(\textbf{x})||^2_2]
当模型收敛的时候, \mathbf{s}\theta(\textbf{x}) \mathbf{s}\theta(\textbf{x}) 形成的向量场,沿着 \mathbf{s}\theta(\textbf{x}) \mathbf{s}\theta(\textbf{x}) 行走就能找到 p(\textbf{x}) 的最大值。这里的 \mathbf{s}_\theta(\textbf{x}) 就是 p(\textbf{x}) 的score function
DDPM的另外一种理解
DDPM跟score function会有什么关系呢?
考虑高斯分布 z \sim \mathcal{N}(\mu, \sigma^2) ,当我们有了 z 的观测之后,对于均值 \mu 的期望满足Tweedie’s Formula
\mathbb{E}(\mu|z)=z + \sigma^2 \nabla_z \log p(z)
回想DDPM里面 q(x_t|x_0)=\mathcal{N}(x_t;\sqrt{\bar{\alpha_t}}x_0 , 1-\bar{\alpha_t}) ,因此
\mathbb{E}(\mu_t|x_t)=x_t+(1-\bar{\alpha_t})\nabla_{x_t} \log p(x_t)
另外知道 \mu_t 的最优估计就是 \mathcal{N}(x_t;\sqrt{\bar{\alpha_t}}x_0 , 1-\bar{\alpha_t}) 的均值,即
\sqrt{\bar{\alpha_t}}x_0=\mathbb{E}(\mu_t|x_t)=x_t+(1-\bar{\alpha_t})\nabla_{x_t} \log p(x_t)
因此 x_0 可以用 \nabla_{x_t} \log p(x_t) 表示出来
x_0=\frac{x_t+(1-\bar{\alpha_t})\nabla_{x_t} \log p(x_t)}{\sqrt{\bar{\alpha_t}}}
将 x_0 带入求 \mu_t(x_t,x_0) 的公式(7),可以得到
\mu_t(x_t,x_0)=\frac{1}{\sqrt{\alpha_t}} x_t + \frac{1-\alpha_t}{\sqrt{\alpha_t}}\nabla_{x_t}\log p(x_t)
到了这里,跟前面DDPM的 $\epsilon\theta(x_t, t)$$\bar{\epsilon}t$ 类似,这里可以用 s\theta(x_t, t) s\theta(x_t, t) 来拟合 \nabla{x_t}\log p(x_t) \nabla{x_t}\log p(x_t) ,即
\begin{align} L_{t-1} &\propto ||s_\theta(x_t, t)-\nabla_{x_t}\log p(x_t)||^2_2 \end{align}
训练完成后。在推理采样的时候,先得到 s_\theta(x_t, t) 之后,然后计算
\mu_\theta(x_t,x_0)=\frac{1}{\sqrt{\alpha_t}} x_t + \frac{1-\alpha_t}{\sqrt{\alpha_t}}s_\theta(x_t, t)
然后采样得到 x_{t-1}
x_{t-1}=\mathcal{N}(x_{t-1};\mu_\theta(x_t,x_0),\beta_t)
因此我们得到了另外一个理解DDPM的角度,就是用网络 s\theta(x_t, t) s\theta(x_t, t) 来预测 \nabla{x_t}\log p(x_t) \nabla{x_t}\log p(x_t) ## DDIMDDIM的出发点是希望能缩减采样次数。观察DDPM的递推公式
x_{t-1}=q(x_{t-1}|x_0)=\sqrt{\bar{\alpha}_{t-1}}x_0 +\sqrt{1-\bar{\alpha}_{t-1}}\bar{\epsilon}_{t-1}
DDIM开了两个脑洞- 脑洞1:把高斯分布 \bar{\epsilon}{t-1} \bar{\epsilon}{t-1} 拆成两个高斯分布 \bar{\epsilon}t \bar{\epsilon}t 和 \epsilon 的和- 脑洞2:无中生有 x_0 ,通过 x_t 和 \bar{\epsilon}t \bar{\epsilon}t 估计 x_0 ,并用在 x{t-1} x{t-1} 求解上
\begin{align} x_{t-1} &\approx \sqrt{\bar{\alpha}_{t-1}}x_0 +\sqrt{1-\bar{\alpha}_{t-1}-\sigma_t^2}\bar{\epsilon}_{t}+\sigma_t \epsilon \\ &\approx \sqrt{\bar{\alpha}_{t-1}}(\frac{x_t-\sqrt{1-\bar{\alpha}}_t \bar{\epsilon_t}}{\sqrt{\bar{\alpha}}})+\sqrt{1-\bar{\alpha}_{t-1}-\sigma_t^2}\bar{\epsilon}_{t}+\sigma_t \epsilon \end{align}
如果让U-Net网络学习 \bar{\epsilon}t \bar{\epsilon}t ,即 \epsilon\theta^t(x_t) \epsilon\theta^t(x_t) ,则可得到最终表达式
x_{t-1}=\sqrt{\bar{\alpha}_{t-1}}(\frac{x_t-\sqrt{1-\bar{\alpha}}_t \cdot \epsilon_\theta^t(x_t)}{\sqrt{\bar{\alpha}}})+\sqrt{1-\bar{\alpha}_{t-1}-\sigma_t^2} \cdot\epsilon_\theta^t(x_t)+\sigma_t \epsilon
可见每一次递推,先根据 x_t 和本次的方差估计 \epsilon\theta^t(x_t) \epsilon\theta^t(x_t) 推出 x_0 ,然后再正向推出 x{t-1} x{t-1} 注意这里的方差为 \sigma_t ,回想原来DDPM里面的方差为
\sigma_t^2(x_t, x_0)=\frac{1-\bar{\alpha}_{t-1}}{1-\bar{\alpha}_t} \cdot \beta_t
因此要方差可比的话
\sigma_t^2=\frac{1-\bar{\alpha}_{t-1}}{1-\bar{\alpha}_t} \cdot \beta_t=\eta \cdot \beta_t
可见要求 \eta 非负。如果 \eta=0 就变成确定性过程,这个就是DDIM。即
x_{t-1}=\sqrt{\bar{\alpha}_{t-1}}(\frac{x_t-\sqrt{1-\bar{\alpha}}_t \cdot \epsilon_\theta^t(x_t)}{\sqrt{\bar{\alpha}}})+\sqrt{1-\bar{\alpha}_{t-1}} \cdot\epsilon_\theta^t(x_t)
因此DDIM主要把reverse过程变成了确定性过程,并且缩减了采样次数## Classifier-GuidedDDPM和DDIM生成的图片虽然视觉上效果还可以,但是在FID等指标上一直比不过GAN,直到出现了Classifier-Guided的方法,本质上是牺牲了一定的多样性,提高了保真度。DDPM过程我们想知道DDPM中加入了标签 y 之后会对 x_t 的生成有什么影响,注意此时模型的encoder过程不变。从 p(x_t|x_{t+1}, y) 原始定义出发,贝叶斯公式展开,最终可以得到下列公式
\begin{align} p(x_t|x_{t+1},y) &= \frac{p(x_t|x_{t+1})p(y|x_t, x_{t+1})p(x_{t+1})}{p(y|x_{t+1})p(x_{t+1})}\\ &= \frac{p(x_t|x_{t+1})p(y|x_t)}{p(y|x_{t+1})}\\ &= Z \cdot p_\theta(x_t|x_{t+1}) \cdot p_\phi(y|x_t) \end{align}
推导Hint如下- y 与 x{t+1} x{t+1} 独立,因此 p(x{t+1}|x_t, y)=p(x{t+1}|x_t) p(x{t+1}|x_t, y)=p(x{t+1}|x_t) p(x{t+1}|x_t, y)=p(x{t+1}|x_t) - y 取值对给定的图而言是确定的,因此 p(y|x{t+1})=p(y)=\text{const} p(y|x{t+1})=p(y)=\text{const} 左右取对数,对 \log p_\phi(y|x_t) 添加尺度因子 s ,可得
\log p(x_t|x_{t+1}, y) = \log p_\theta(x_t|x_{t+1}) + s \cdot \log p_\phi(y|x_t)\\
进一步分析(完整推导见文章)- \log p\theta(x_t|x{t+1}) \log p\theta(x_t|x{t+1}) \log p\theta(x_t|x{t+1}) 项。从DDPM中知道是个高斯分布,可以通过 \epsilon\theta(x_t, t) \epsilon\theta(x_t, t) 求出均值 \mu\theta(x_t, t) \mu\theta(x_t, t) ,因此 \log p\theta(x_t|x{t+1}) \log p\theta(x_t|x{t+1}) \log p\theta(x_t|x{t+1}) 可以用概率密度写出- \log p\phi(y|x_t) \log p\phi(y|x_t) 项。在 x_t=\mu\theta(x_t, t) x_t=\mu\theta(x_t, t) 做泰勒展开最终表达式为
\begin{align} \log p(x_t|x_{t+1}, y) &= \log p(z) + C,\ \ z \sim \mathcal{N}(\mu_\theta(x_t, t)+\sigma\cdot c \cdot\nabla_{x_t}\log p_\phi(y|x_t), \sigma^2) \end{align}
最终推理方式如下所示,本质上是对均值做一下修正
DDIM过程
由于DDIM是个确定性过程, p(x_t|x{t+1}) p(x_t|x{t+1}) 是个确定性映射过程,不是分布。目标对象从 p(x_t|x{t+1}, y) p(x_t|x{t+1}, y) 退化成了 p(x_t|y) 。根据贝叶斯公式
p(x_t|y)=\frac{p(y|x_t)\cdot p(x_t)}{p(y)}
两边取对数,并且对 x_t 求导数(注意 y 不能由 x_t 表出,因此 \nabla_{x_t}\log p(y) 导数为0)
\begin{align} \nabla_{x_t}\log p(x_t|y) &= \nabla_{x_t}\log p(y|x_t)+\nabla_{x_t}\log p(x_t)-\nabla_{x_t}\log p(y)\\ &= \nabla_{x_t}\log p(y|x_t)+\nabla_{x_t}\log p(x_t) \end{align}
对 \nabla_{x_t}\log p(y|x_t) 加入尺度因子,方便做标签强度调整
\begin{align} \nabla_{x_t}\log p(x_t|y) =\nabla_{x_t}\log p(x_t) + \gamma \cdot \nabla_{x_t}\log p(y|x_t) \end{align}
从论文结论可知,借助score function的结论
\nabla_{x_t}\log p(x_t)=-\frac{1}{\sqrt{1-\bar{\alpha}_t}}\epsilon(x_t)
于是代入整理可得,并且对概率进行参数化(这里 p_\phi(y|x_t) 就是分类器)
-\frac{1}{\sqrt{1-\bar{\alpha}_t}}\epsilon_\theta^t(x_t|y)=-\frac{1}{\sqrt{1-\bar{\alpha}_t}}\epsilon_\theta^t(x_t)+\gamma \cdot \nabla_{x_t}\log p_\phi(y|x_t)
整理可以得到
\epsilon_\theta^t(x_t|y)=\epsilon_\theta^t(x_t)-\sqrt{1-\bar{\alpha}_t} \cdot\gamma \cdot \nabla_{x_t}\log p_\phi(y|x_t)
在求出 \epsilon\theta^t(x_t) \epsilon\theta^t(x_t) 之后,用分类器的梯度对其修正,求出 \epsilon\theta^t(x_t|y) \epsilon\theta^t(x_t|y) 后替换原始的 \epsilon_\theta^t(x_t) 。然后再代入DDIM的递推公式中。完整Classifier guided DDIM算法如下
Classifier-freeguidance
训练虽然能提高保真度,但是问题很多- 但是无论是DDPM还是DDIM的推理过程,每一步都需要计算梯度,操作很贵- classifier本身是扛噪音输入的特供版,需要重新训练,例如noisy-CLIP模型能否既得到高保真度结果,又能在推理时免去梯度计算呢?guidance-free应运而生,本质是在训练阶段就想办法提高模型的能力,免去了推理时候的梯度计算。网络首先把condition吃进来,注意这个condition要跟数据相关,例如- 分类的话就是待生成图片的类别- 文生图的话就是文字的embedding训练阶段随机概率把输入condition置为空,即概率性 \epsilon\theta(x_t|y) \rightarrow \epsilon\theta(x_t|\varnothing) \epsilon\theta(x_t|y) \rightarrow \epsilon\theta(x_t|\varnothing) \epsilon\theta(x_t|y) \rightarrow \epsilon\theta(x_t|\varnothing) 推理采样阶段,用下面公式做采样
\hat{\epsilon}_\theta(x_t|y)=(1+w)\cdot \epsilon_\theta(x_t|y)-w\cdot\epsilon_\theta(x_t|\varnothing)
其中 w 为引导强度,一般认为 w>0 会使生成往有condition和无condition差异比较大的方向走,引导强度越大,越牺牲多样性提高保真度。这里的 y 也可以换成其他condition。
小结
生成模型背后有大量的数学原理,本质上想解决如何生成 p(X) 的问题,各类方法总结如下
AIGC评价指标
生成的多模态内容往往包含很强的主观色彩,因此评价相对比较困难,本节我们介绍常见额两种图片生成质量指标,IS(Inception Score) 和 FID (Frechet Inception Distance)
IS指标
Inception Score (IS) 是个非常启发式的指标,本质上利用“Inception网络对于真实图片有很好的判别能力”这个特性而设计得到的,理解这个指标有两个角度,一个是互信息角度,一个是KL散度角度。符号定义如下- x 是个随机变量,由图片生成网络 G 产生。假设 G 生成的图片集合为 X_G , G 生成图片的分布为 P_G ,则 x \in X_G 且 x \sim P_G
- y 是个随机变量,取值离散集合为 L_Y= {1, 2, \cdots, 1000} 。假设inception网络经过softmax后1000分类的概率向量为 \mathbf{p} ,则 y \in L_Y 且 p(y=i)=\mathbf{p}_i
我们可以从两个角度理解这个指标,互信息角度和KL散度角度。
互信息
首先从互信息角度考虑,考察互信息 I(y;x) ,衡量的是两个随机变量 y 和 x 的依赖情况
- 情况1:如果 x 是随机噪声图片,那么 x 的信息对决定 y 没有任何帮助, x 和 y 完全独立不相关,则 I(y;x)=0
- 情况2:如果 x 就是ImageNet的图片全集,那么只要 x 就完全能决定 y 的分布,两者完全相关,此时 I(y; x) 应该取到最大值
由此我们知道, I(y;x) 跟 x 的真实程度有一定的正相关性。如果我们继续分析 I(y;x) ,想知道最大的 I(y;x) 应该满足什么条件。可以通过互信息公式得到
I(y;x) = H(y) - H(y|x)
如果想最大化这个指标,那么
- 多样性: 最大化第一项 H(y) ,如果 y 的分布越均匀,多样性越大,不出现模态坍缩, H(y) 才能越大,当 y 为均匀分布的时候
- 清晰度: 最小化第二项 H(y|X) ,即代表给定图片 x 后的标签 y 的熵,分布越尖峰,越接近one-hot, H(y|X) 才能越小
由上我们知道 I(y;x) 的最大值为
\begin{align}I_\text{max}(y; x)&=H(y)-0\\&=-\sum_{i=1}^{1000}\frac{1}{1000}\ln(\frac{1}{1000})\\&=\ln(1000)\end{align}
KL散度
换一个角度,考察KL散度,给出IS的标准定义
\text{IS}(G)=\exp(\mathbb{E}_{x\sim {P_G}}\text{KL}(p(y|x)||p(y))
这个式子看起来很复杂,但是其实通过数学推导会发现等价于上述的 I(y;x) ,完整推导如下
\begin{align}\ln(\text{IS}(G))&=\mathbb{E}_{x\sim {P_G}}\text{KL}(p(y|x)||p(y) \\&=\sum_{x\in X_G} p(x)\sum_{y\in L_Y}p(y=i|x)\cdot \ln\frac{p(y=i|x)}{p(y=i)} \\&=\sum_{x\in X_G} \sum_{y\in L_Y} p(y=i, x)\cdot \ln p(y=i|x) - \sum_{x\in X_G} \sum_{y\in L_Y} p(y=i, x)\cdot \ln p(y=i)\\&= -H(y;x) +(- \sum_{y\in L_Y} \ln p(y=i)\sum_{x\in X_G}p(y=i, x)) \\&=-H(y;x)+(- \sum_{y\in L_Y} \ln p(y=i) \cdot p(y=i)) \\&=-H(y;x) + H(y) \\&= I(y;x)\end{align}
因此可以得到
\text{IS}(G)=e^{I(y;x)}
计算代码
条件假设
- 假设我们选取了 N 张图片,分别为 {x_1, x_2, \cdots, x_N}
- 将这N张图喂入inception网络,得到输出的softmax概率tensor为 Z \in \mathbb{R}^{N \times 1000}
- Z(i, j) 相当于 p(y=j|x=x_i) ,即第 i 张图的第 j 个label的概率值
- p(x=x_i)=1/N ,看成均匀分布
- 边缘分布重新写成条件概率求和的方式
\begin{align}p(y=j)&=\sum_{i=1}^Np(y=j, x=x_i)\\&=\sum_{i=1}^N p(x=x_i) \cdot p(y=j|x=x_i) \\&=\frac{1}{N}\sum_{i=1}^N p(y=j|x=x_i)\end{align}
因此可以得到可计算的IS表达,如下所示
\begin{align}\text{IS}(G)&=\exp(\sum_{x\in X_G} p(x)\sum_{y\in L_Y}p(y=i|x)\cdot \ln\frac{p(y=i|x)}{p(y=i)}) \\&=\exp(\sum_{i=1}^N \frac{1}{N}\sum_{j=1}^{1000} p(y=j|x=x_i)\cdot \ln\frac{p(y=j|x=x_i)}{\frac{1}{N}\sum_{k=1}^Np(y=j|x=x_k)}) \\\end{align}
至此终于可以把所有 p(y=j|x=x_i) 用 Z 来替换了,即
\begin{align}\text{IS}(G)&=\exp(\frac{1}{N} \sum_{i=1}^N \sum_{j=1}^{1000} Z(i,j)\cdot \ln\frac{Z(i,j)}{\frac{1}{N}\sum_{k=1}^NZ(k,j)}) \\\end{align}
最终代码如下 (一般切分多个splits来计算,计算均值和方差)
def calculate_inception_score(z_preds, splits=10):
# z_preds: (N, 1000)
scores = []
for i in range(splits):
slice_start = i * z_preds.shape[0] // splits
slice_end = (i + 1) * z_preds.shape[0] // splits
part = z_preds[slice_start:slice_end, :]
kl = part * (np.log(part) - np.log(np.mean(part, 0, keepdims=True)))
kl = np.mean(np.sum(kl, 1))
kl = np.exp(kl)
scores.append(kl)
return np.mean(scores), np.std(scores)
FID指标
指标Frechet是个人名,法国数学家,提出了Frechet Distance概念。
Frechet Inception Distance(FID)指标计算过程如下
- 给出了生成图片集合 X_G 和真实图片集合 X_R ,集合大小分别为 N 和 M
- X_G 和 X_R 经过Inception v3得到对应feature集合 F_G \in \mathbb{R}^{N \times D} 和 F_R \in \mathbb{R}^{M \times D}
- 将 F_G 和 F_R 分别看成是来自于某分布 P_G 和 P_R 的样本点, \mu_G 和 \Sigma_G 分别是 P_G 的均值和协方差,同理 \mu_R 和 \Sigma_R 分别是 P_R 的均值和协方差
- 在 P_G 和 P_R 是多元高斯分布的假设前提下,按照FD定义可以求解得到
\text{FID}(X_G, X_R)=\text{FD}(P_G, P_R)=||\mu_G-\mu_R||^2_2+\text{Tr}(\Sigma_G+\Sigma_R-2(\Sigma_G \Sigma_R)^{\frac{1}{2}})
提供一些个人直观理解
- FID是衡量生成图片和真实图片的距离,数值越小越好
- FD指标数学定义比较复杂,也叫2-Wasserstein距离,跟最优传输理论相关
- FD指标本身是个下界值,含义可以理解为,把概率分布 P_G 投射到概率分布 P_R 的解期望传输代价最小值,详细数学定义见wiki
计算FD指标的代码如下
import numpy as np
from scipy import linalg
def calculate_frechet_distance(feat_G, feat_R, eps=1e-6):
# feat_G: (N, D)
# feat_R: (M, D)
mu1, sigma1 = np.mean(feat_G, axis=0), np.cov(feat_G.T)
mu2, sigma2 = np.mean(feat_R, axis=0), np.cov(feat_R.T)
diff = mu1 - mu2
# product might be almost singular
covmean, _ = linalg.sqrtm(sigma1.dot(sigma2), disp=False)
if not np.isfinite(covmean).all():
offset = np.eye(sigma1.shape[0]) * eps
covmean = linalg.sqrtm((sigma1 + offset).dot(sigma2 + offset))
# numerical error might give slight imaginary component
if np.iscomplexobj(covmean):
if not np.allclose(np.diagonal(covmean).imag, 0, atol=1e-3):
m = np.max(np.abs(covmean.imag))
raise ValueError("Imaginary component {}".format(m))
covmean = covmean.real
tr_covmean = np.trace(covmean)
return diff.dot(diff) + np.trace(sigma1) + np.trace(sigma2) - 2 * tr_covmean
小结
- IS指标计算有很强的先验,认为符合ImageNet的分布才是真实分布
- FID指标衡量两个数据集的距离,更科学一点
写在最后
本文一共分了2个小节
- 首先介绍了生成模型的本质目的,就是为了建模 p(x)
分布。
- 首先是最朴素的极大似然估计,虽然简单,但是要求有明确的参数化分布形式,在实际中往往不可得
- 接着介绍4种隐变量模型,包括VAE,GAN,Flow Model和Diffusion Model。本质上用 p(x)=\int p(x|z) p(z) \text{d}z 来近似
- VAE模型。尝试提高 p(z) 采样效率,尝试最小化 \text{KL}(q_\theta(z|x)||p(z)) ,最终得到了正则项和重建误差项
- GAN模型。尝试对MSE的损失函数做进一步拓展,引入判别模型 D(x', x) 来隐式学习度量方法
- Flow Model模型。强行让 f 函数可逆,满足 x 和 z 的一一映射,以RevNet为例子介绍Flow Model具体使用方式
- Diffusion Model (DDPM)。将VAE扩展到了多步,有复杂的数学推导,但是本质上跟VAE是相似的
- DDPM的score function。换一种角度理解DDPM,发现可以用网络 s\theta(x_t, t) s\theta(x_t, t) 来预测 \nabla{x_t}\log p(x_t) \nabla{x_t}\log p(x_t)
- DDIM。尝试对DDPM做采样加速,将DDPM变成了确定性的过程
- classifier-guided。使用classifier-guided技术,首次把DDPM和DDIM的IS和FID指标拉高到GAN齐平。在推理阶段,DDPM可以直接分析 p(x_t|x_{t+1}, y) ;而对于DDIM,由于是个确定性过程,因此退化成分析 p(x_t|y)
- classifier-free。为了省去classifier-guided的梯度计算过程,classifier-free在训练中混合训练有condition和无condition的模型,使得在推理阶段无需求解梯度,在提高保真度的同时计算效率也很高
- 接着介绍了图片生成常见的两种指标
- IS(Inception Score)指标提供了两种理解角度。IS本身有很强的先验,认为符合ImageNet的分布才是真实分布
- FID(Frechet Inception Distance) 指标,衡量两个数据集的距离,更科学一点
预告:计划下一篇为《AIGC组成原理(下)》,将介绍具体的Image生成、Video生成、Audio生成和3D生成算法,敬请期待。
PS:由于笔者小A并没有亲手撸过上述内容的所有细节,大部分是通过研究代码和精读优秀文章的方式 bottom-up 总结而来,本质上是个拾人牙慧的知识搬运工,所以终究是纸上谈兵。因此希望各方有实际经验的大佬猛锤,思维碰撞才生火花,真理越辩越明。
如果想了解transformer在NLP/多模态/AIGC的算法知识,分布式训练的知识,以及如何在TVM上做PTQ量化和部署,可以关注我aaronxic哟~
系列文章导览
参考资料
- AIGC的一些记录
- 从零推导:变分自编码器(VAE)
- 变分自编码器(一):原来是这么一回事 - 科学空间|Scientific Spaces
- 细水长flow之NICE:流模型的基本概念与实现 - 科学空间|Scientific Spaces
- 生成扩散模型漫谈(一):DDPM = 拆楼 + 建楼 - 科学空间|Scientific Spaces
- What are Diffusion Models?
- 扩散模型之DDPM
- PyTorch 32.Gumbel-Softmax Trick
- [论文理解] Diffusion Models Beat GANs on Image Synthesis
- 谈谈扩散模型的损失函数
- 哪位大神解释下inception score? - 知乎
- GAN的评价指标IS和FID_fid评价指标_汐梦聆海的博客-CSDN博客
- 互信息 - 维基百科,自由的百科全书
- IS、FID、PPL,GAN网络评估指标
- Fréchet inception distance
- 令人拍案叫绝的Wasserstein GAN