生成扩散模型漫谈(一):DDPM = 拆楼 + 建楼

date
Jul 7, 2022
Last edited time
Mar 27, 2023 08:44 AM
status
Published
slug
生成扩散模型漫谈(一):DDPM=拆楼+建楼
tags
DL
DDPM
summary
转载. 2022.09.06@修改了一些网页的显示问题 2022.10.14@修改了一些网页显示的问题
type
Post
Field
Plat
说到生成模型,VAE、GAN 可谓是 “如雷贯耳”。此外,还有一些比较小众的选择,如 flow 模型、VQ-VAE 等,也颇有人气,尤其是 VQ-VAE 及其变体 VQ-GAN,近期已经逐渐发展到 “图像的 Tokenizer” 的地位,用来直接调用 NLP 的各种预训练方法。除了这些之外,还有一个本来更小众的选择——扩散模型(Diffusion Models)——正在生成模型领域“异军突起”,当前最先进的两个文本生成图像——OpenAI 的 DALL·E 2 和 Google 的 Imagen,都是基于扩散模型来完成的。
Imagen“文本 - 图片” 的部分例子
Imagen“文本 - 图片” 的部分例子
 
从本文开始,我们开一个新坑,逐渐介绍一下近两年关于生成扩散模型的一些进展。据说生成扩散模型以数学复杂闻名,似乎比 VAE、GAN 要难理解得多,是否真的如此?扩散模型真的做不到一个 “大白话” 的理解?让我们拭目以待。

新的起点

能量视角下的GAN模型-EBMs
这篇文章就是指出能量模型实际上就是某个特定的 Langevin 方程的静态解,然后就用这个 Langevin 方程来实现采样,有了采样过程也就可以完成能量模型的训练。 跟 《能量视角下的 GAN 模型(二):GAN="分析"+"采样"》 一样,假设我们有一批数据,我们希望用一个概率模型去拟合它,我们选取的模型为 其中 是带参数 的未定函数,我们称为 "能量函数",而 是归一化因子(配分函数) 这样的分布可以称为 "能量分布",在物理中也被称为 "玻尔兹曼分布"。 越小越好,为此,我们对 使用梯度下降。我们有(具体推导参考上面链接) 这里的能量函数 , 相当是 , 即 . 在式 (5) 中,是容易估算的,直接抽样一批真实数据来计算就行了;但是 却很困难,因为我们不知道怎么实现从 中采样。 重要采样 思路是定义另外一个容易采样的分布 ,然后改为从 中采样,同时去缩小 和 的差异,使得 确实可以成为 的一个良好近似。但这篇论文不一样,它直接从能量模型对应的 Langevin 方程采样。 Langevin 方程: 马尔可夫链由一个随机状态 和一个转移分布 定义而成, 是一个概率分布,说明了给定状态 的情况下随机地转移到 的概率。运行一个马尔可夫链意味着根据转移分布 采出的值 来更新状态 。 从状态 到新状态 ′ 。单一状态转移到 的概率可以表示为 .
能量视角下的GAN模型-EBMs
说到扩散模型,一般的文章都会提到能量模型(Energy-based Models)、得分匹配(Score Matching)、朗之万方程(Langevin Equation)等等,简单来说,是通过得分匹配等技术来训练能量模型,然后通过郎之万方程来执行从能量模型的采样。
从理论上来讲,这是一套很成熟的方案,原则上可以实现任何连续型对象(语音、图像等)的生成和采样。但从实践角度来看,能量函数的训练是一件很艰难的事情,尤其是数据维度比较大(比如高分辨率图像)时,很难训练出完备能量函数来;另一方面,通过朗之万方程从能量模型的采样也有很大的不确定性,得到的往往是带有噪声的采样结果。所以很长时间以来,这种传统路径的扩散模型只是在比较低分辨率的图像上做实验。
如今生成扩散模型的大火,则是始于 2020 年所提出的 DDPM(Denoising Diffusion Probabilistic Model),虽然也用了 “扩散模型” 这个名字,但事实上除了采样过程的形式有一定的相似之外,DDPM 与传统基于朗之万方程采样的扩散模型可以说完全不一样,这完全是一个新的起点、新的篇章。
准确来说,DDPM 叫 “渐变模型” 更为准确一些,扩散模型这一名字反而容易造成理解上的误解,传统扩散模型的能量模型、得分匹配、朗之万方程等概念,其实跟 DDPM 及其后续变体都没什么关系。有意思的是,DDPM 的数学框架其实在 ICML2015 的论文《Deep Unsupervised Learning using Nonequilibrium Thermodynamics》就已经完成了,但 DDPM 是首次将它在高分辨率图像生成上调试出来了,从而引导出了后面的火热。由此可见,一个模型的诞生和流行,往往还需要时间和机遇,

拆楼建楼

变分推断看这里
DL花书阅读笔记-近似推断
在深度学习中,通常我们有一系列可见变量 和一系列潜变量 。 推断(inference)指给定一些其他变量的情况下计算某些变量概率分布的过程, 推断困难 通常是指难以计算 或其期望。通常源于结构化图模型中潜变量之间的相互作用。 许多仅含一个隐藏层的简单图模型会定义成易于计算 或其期望的形式,例如受限玻尔兹曼机和概率 PCA。不幸的是,大多数具有多层隐藏变量的图模型的后验分布都很难处理。对于这些模型而言,精确推断算法需要指数量级的运行时间。即使一些只有单层的模型,如稀疏编码,也存在着这样的问题。 因为 和 之间的距离是由 散度来衡量的,且 散度总是非负的,我们可以发现: 通过简单的代数运算我们可以把 重写成一个更加简单的形式: 这里使用的 即为 的简化写法, 如 . 在潜变量模型中期望最大化(expectation maximization, EM)算法,是一个非常常见的训练算法。与大多数我们在本章中介绍的其他算法不同的是,EM 并不是一个近似推断算法,而是一种能够学到近似后验的算法。 E 步(expectation step): 更新更准确的分布 来最大化 . 令 表示在这一步开始时的参数值。对任何我们想要训练的(对所有的或者小批量数据均成立)索引为 的训练样本 ,令 。通过这个定义,我们认为 在当前参数 下定义。如果我们改变 ,那么 将会相应地变化,但是 还是不变并且等于 。 M 步(maximization step):更新 来最大化 . 使用选择的优化算法完全地或者部分地关于 最大化 .
DL花书阅读笔记-近似推断
很多文章在介绍 DDPM 时,上来就引入转移分布,接着就是变分推断,一堆数学记号下来,先吓跑了一群人(当然,从这种介绍我们可以再次看出,DDPM 实际上是 VAE 而不是扩散模型),再加之人们对传统扩散模型的固有印象,所以就形成了 “需要很高深的数学知识” 的错觉。事实上,DDPM 也可以有一种很 “大白话” 的理解,它并不比有着 “造假 - 鉴别” 通俗类比的 GAN 更难。
首先,我们想要做一个像 GAN 那样的生成模型,它实际上是将一个随机噪声 变换成一个数据样本 的过程:
我们可以将这个过程想象为 “建设”,其中随机噪声 是砖瓦水泥等原材料,样本数据 是高楼大厦,所以生成模型就是一支用原材料建设高楼大厦的施工队。
这个过程肯定很难的,所以才有了那么多关于生成模型的研究。但俗话说 “破坏容易建设难”,建楼你不会,拆楼你总会了吧?我们考虑将高楼大厦一步步地拆为砖瓦水泥的过程:设 为建好的高楼大厦(数据样本),为拆好的砖瓦水泥(随机噪声),假设 “拆楼” 需要 步,整个过程可以表示为
建高楼大厦的难度在于,从原材料 到最终高楼大厦 的跨度过大,普通人很难理解 是怎么一下子变成 的。但是,当我们有了 “拆楼” 的中间过程 后,我们知道 代表着拆楼的一步,那么反过来 不就是建楼的一步?如果我们能学会两者之间的变换关系 ,那么从 出发,反复地执行 、…,最终不就能造出高楼大厦 出来?

该怎么拆

DDPM 做生成模型的过程,先反过来构建一个从数据样本渐变到随机噪声的过程,然后再考虑其逆变换,通过反复执行逆变换来完成数据样本的生成,所以本文前面才说 DDPM 这种做法其实应该更准确地称为 “渐变模型” 而不是“扩散模型”。
具体来说,DDPM 将数据样本渐变到随机噪声的过程(Encoding)建模为
其中有 通常很接近于 ,噪声 的引入代表着对原始信号的一种破坏,即每一步中我们都将 拆解为 “的楼体 + 的原料”。(提示:本文 ,  的定义跟原论文不一样。)
反复执行这个步骤,我们可以得到:
可能刚才读者就想问为什么叠加的系数要满足了,现在我们就可以回答这个问题。首先,式中花括号所指出的部分,正好是多个独立的正态噪声之和,其均值为 ,方差则分别为 ;然后,我们利用一个概率论的知识——正态分布的叠加性,即上述多个独立的正态噪声之和的分布,实际上是均值为 、方差为 的正态分布;最后,在 恒成立之下,我们知道:
所以实际上相当于有
这就为计算 提供了极大的便利。另一方面,DDPM 会选择适当的 形式,使得有 ,这意味着经过 步的拆楼后,所剩的楼体几乎可以忽略了,已经全部转化为原材料 。(提示:本文 的定义跟原论文不一样。)

又如何建

“拆楼” 是 的过程,这个过程我们得到很多的数据对 ,那么 “建楼” 自然就是从这些数据对中学习一个模型 。那么容易想到学习方案就是最小化两者的欧氏距离:
其实这已经非常接近最终的 DDPM 模型了,接下来让我们将这个过程做得更精细一些。首先 可以改写为 ,这启发我们或许可以将 “建楼” 模型 设计成
的形式,其中 是训练参数,将其代入到损失函数,得到
就是使用 来预测损坏过程引入的噪声 , 这样这个恢复过程就能利用这个预测出来的噪声恢复出原始信号.
前面的因子 代表 loss 的权重,这个我们可以暂时忽略,最后代入结合式 所给出 的表达式:
得到损失函数的形式为
可能读者想问为什么要回退一步来给出 ,直接给出 可以吗?答案是不行,因为我们已经事先采样了,而 不是相互独立的,所以给定 的情况下,我们不能完全独立地采样

降低方差

原则上来说,通过上面的损失函数就可以完成 DDPM 的训练,但它在实践中可能有方差过大的风险,从而导致收敛过慢等问题。要理解这一点并不困难,只需要观察到 实际上包含了 4 个需要采样的随机变量:
1、从所有训练样本中采样一个 ; 2、从正态分布 中采样 (两个不同的采样结果, 它们相互独立); 3、从 中采样一个 t
要采样的随机变量越多,就越难对损失函数做准确的估计,反过来说就是每次对损失函数进行估计的波动(方差)过大了。很幸运的是,我们可以通过一个积分技巧来将 , 合并成单个正态随机变量,从而缓解一下方差大的问题。
这个积分确实有点技巧性,但也不算复杂。由于正态分布的叠加性,我们知道 实际上相当于单个随机变量 ,同理 实际上相当于单个随机变量 ,并且可以验证 ,所以这是两个相互独立的正态随机变量。
由于 , 可以得到
接下来,我们反过来将 重新表示出来. 由于
可以得到:
代入到式 得到
注意到,现在损失函数关于 只是二次的,所以我们可以展开然后将它的期望直接算出来,结果是
再次省掉常数和损失函数的权重,我们得到 DDPM 最终所用的损失函数:
提示:原论文中的 实际上就是本文的 ,所以大家的结果是完全一样的。)

递归生成

至此,我们算是把 DDPM 的整个训练流程捋清楚了。内容写了不少,你要说它很容易,那肯定说不上,但真要说非常困难的地方也几乎没有——没有用到传统的能量函数、得分匹配等工具,甚至连变分推断的知识都没有用到,只是借助 “拆楼 - 建楼” 的类比和一些基本的概率论知识,就能得到完全一样的结果。所以说,以 DDPM 为代表的新兴起的生成扩散模型,实际上没有很多读者想象的复杂,它可以说是我们从 “拆解 - 重组” 的过程中学习新知识的形象建模。
训练完之后,我们就可以从一个随机噪声 出发执行 来进行生成:
这对应于自回归解码中的 Greedy Search。如果要进行 Random Sample,那么需要补上噪声项:
一般来说,我们可以让 ,即正向和反向的方差保持同步。这个采样过程跟传统扩散模型的朗之万采样不一样的地方在于:DDPM 的采样每次都从一个随机噪声出发,需要重复迭代 步来得到一个样本输出;朗之万采样则是从任意一个点出发,反复迭代无限步,理论上这个迭代无限步的过程中,就把所有数据样本都被生成过了。所以两者除了形式相似外,实质上是两个截然不同的模型。
从这个生成过程中,我们也可以感觉到它其实跟 Seq2Seq 的解码过程是一样的,都是串联式的自回归生成,所以生成速度是一个瓶颈,DDPM 设了 ,意味着每生成一个图片,需要将 反复执行 次,因此 DDPM 的一大缺点就是采样速度慢,后面有很多工作都致力于提升 DDPM 的采样速度。而说到 “图片生成 + 自回归模型 + 很慢”,有些读者可能会联想到早期的 PixelRNNPixelCNN 等模型,它们将图片生成转换成语言模型任务,所以同样也是递归地进行采样生成以及同样地慢。那么 DDPM 的这种自回归生成,跟 PixelRNN/PixelCNN 的自回归生成,又有什么实质区别呢?为什么 PixelRNN/PixelCNN 没大火起来,反而轮到了 DDPM?
了解 PixelRNN/PixelCNN 的读者都知道,这类生成模型是逐个像素逐个像素地生成图片的,而自回归生成是有序的,这就意味着我们要提前给图片的每个像素排好顺序,最终的生成效果跟这个顺序紧密相关。然而,目前这个顺序只能是人为地凭着经验来设计(这类经验的设计都统称为 “Inductive Bias”),暂时找不到理论最优解。换句话说,PixelRNN/PixelCNN 的生成效果很受 Inductive Bias 的影响。但 DDPM 不一样,它通过“拆楼” 的方式重新定义了一个自回归方向,而对于所有的像素来说则都是平权的、无偏的,所以减少了 Inductive Bias 的影响,从而提升了效果。此外,DDPM 生成的迭代步数是固定的 ,而 PixelRNN/PixelCNN 则是等于图像分辨率(宽 × 高 × 通道数),所以 DDPM 生成高分辨率图像的速度要比 PixelRNN/PixelCNN 快得多。

超参设置

这一节我们讨论一下超参的设置问题。
在 DDPM 中,,可能比很多读者的想象数值要大,那为什么要设置这么大的 呢?另一边,对于 的选择,将原论文的设置翻译到本博客的记号上,大致上是
这是一个单调递减的函数,那为什么要选择单调递减的 呢?
其实这两个问题有着相近的答案,跟具体的数据背景有关。简单起见,在重构的时候我们用了欧氏距离作为损失函数,而一般我们用 DDPM 做图片生成,以往做过图片生成的读者都知道,欧氏距离并不是图片真实程度的一个好的度量,VAE 用欧氏距离来重构时,往往会得到模糊的结果,除非是输入输出的两张图片非常接近,用欧氏距离才能得到比较清晰的结果,所以选择尽可能大的 ,正是为了使得输入输出尽可能相近,减少欧氏距离带来的模糊问题。
选择单调递减的 也有类似考虑。当 比较小时, 还比较接近真实图片,所以我们要缩小 的差距,以便更适用欧氏距离,因此要用较大的 ;当 比较大时, 已经比较接近纯噪声了,噪声用欧式距离无妨,所以可以稍微增大 的差距,即可以用较小的 。那么可不可以一直用较大的 呢?可以是可以,但是要增大 。注意应该有 ,而我们可以直接估算
代入 大致是 ,这个其实就刚好达到  的标准。所以如果从头到尾都用较大的 ,那么必然要更大的 才能使得 了。
最后我们留意到,“建楼” 模型中的 中,我们在输入中显式地写出了 ,这是因为原则上不同的 处理的是不同层次的对象,所以应该用不同的重构模型,即应该有 个不同的重构模型才对,于是我们共享了所有重构模型的参数,将 作为条件传入。按照论文附录的说法,是转换成位置编码后,直接加到残差模块上去的。

© Lazurite 2021 - 2024