第 18 章 扩散模型(Diffusion models)
本章一句话:扩散模型先用一个固定的、不可学习的”加噪”过程把数据一步步搅成纯高斯噪声,再训练一个神经网络学会逐步去噪——而这个网络真正要做的事,本质上只是”看一眼带噪图,把里面混进去的噪声预测出来”。
读这章的收获:理解前向加噪与反向去噪两条链路、看懂关键公式 \(z_t=\sqrt{\alpha_t}\,x+\sqrt{1-\alpha_t}\,\epsilon\)、明白训练目标为什么能从复杂的 ELBO 简化成一句”预测噪声”的最小二乘,并对采样、条件生成、无分类器引导与 Stable Diffusion 的核心思想建立直觉。
本章速览
- 两条链路:编码器(前向/扩散过程)把数据 \(x\) 经过一串潜变量 \(z_1\dots z_T\) 逐步混入噪声,直到变成纯白噪声;解码器(反向过程)从噪声出发逐步去噪,重建出数据。两个映射都是随机的,不是确定性的。
- 编码器无参数:前向过程是预先设定好的,没有任何要学的参数。所有可学习的参数都在解码器里——这是扩散模型和 VAE 最大的不同。
- 扩散核是法宝:虽然加噪是一步步来的,但存在闭式公式 \(z_t=\sqrt{\alpha_t}\,x+\sqrt{1-\alpha_t}\,\epsilon\),能一步直接采到任意时刻 \(t\) 的带噪样本,不必逐步迭代。
- 反向用正态近似:每一步的真实反向分布很复杂,但只要前向每步加的噪声足够小、步数足够多,反向每步就能用一个正态分布很好地近似,从而可以用神经网络预测其均值。
- 训练目标 = 预测噪声:从最大化似然出发,借 ELBO(证据下界)一路化简,最终落到一个极其简单的最小二乘损失 \(\|\epsilon-g_t[z_t,\phi_t]\|^2\)——网络只需预测”混进 \(z_t\) 里的那团噪声”。
- 与 VAE 的血缘:扩散模型可看成一个编码器被冻结、潜空间与数据同维的分层 VAE,同样用 ELBO 下界来逼近难以计算的似然。
- 图像生成靠 U-Net:实现上用一个共享所有时间步的 U-Net 来预测噪声(时间步作为额外输入)。采样需串行跑很多步,因此慢。
- 条件生成 + 引导:通过分类器引导、无分类器引导可让生成服从文本/类别条件;级联多个扩散模型 + 语言模型文本编码,就是现代文生图(如 Imagen / Stable Diffusion)的骨架。
18.1 概述
一个扩散模型由编码器和解码器组成:
- 编码器接收一个数据样本 \(x\),把它依次映射成一串中间潜变量 \(z_1,\dots,z_T\)(它们和 \(x\) 同样大小)。
- 解码器反着走:从 \(z_T\) 出发,经 \(z_{T-1},\dots,z_1\),最终(重新)造出一个数据点 \(x\)。
两个方向的映射都是随机的而非确定的。
编码器是预先设定的:它只是把输入和白噪声一点点掺在一起(见下面的”前向过程”直觉图)。步数足够多以后,最后一个潜变量的条件分布 \(q(z_T|x)\) 和边缘分布 \(q(z_T)\) 都会变成标准正态分布。既然这个过程是写死的,那么所有要学的参数都在解码器里。
直觉图(前向过程):想象一滴墨水(数据)滴进清水里,随时间不断扩散、变淡,最终整杯水均匀成一片灰(标准正态)。每一帧就是一个 \(z_t\)。
解码器是学出来的:我们训练一串网络,去学相邻潜变量 \(z_t\) 与 \(z_{t-1}\) 之间的反向映射。损失函数鼓励每个网络去反演对应的那一步加噪。这样一来,噪声被一级级地剥掉,直到剩下一张逼真的数据样本。要生成新样本 \(x\),只需从 \(q(z_T)\)(标准正态)采一个噪声向量,再让它穿过整个解码器即可。
后续小节安排:18.2 细看编码器(它的性质不直观,却对算法至关重要);18.3 讲解码器;18.4 推导训练算法;18.5 把训练目标重写成更实用的形式;18.6 谈实现细节,包括如何让生成服从文本提示。
18.2 编码器(前向加噪过程)
扩散过程(前向过程) 把数据样本 \(x\) 经过一串与 \(x\) 同尺寸的中间变量 \(z_1,z_2,\dots,z_T\),规则是:
\[ z_1 = \sqrt{1-\beta_1}\cdot x + \sqrt{\beta_1}\cdot \epsilon_1 \]
\[ z_t = \sqrt{1-\beta_t}\cdot z_{t-1} + \sqrt{\beta_t}\cdot \epsilon_t,\qquad t\in\{2,\dots,T\}, \]
其中 \(\epsilon_t\) 是从标准正态分布采的噪声。可以这样读这条公式:
- 第一项 \(\sqrt{1-\beta_t}\cdot z_{t-1}\) —— 把”目前为止的数据 + 已加噪声”按比例衰减一点点(让它向 0 收缩);
- 第二项 \(\sqrt{\beta_t}\cdot \epsilon_t\) —— 再掺入一份新噪声。
超参数 \(\beta_t\in[0,1]\) 决定噪声掺入的快慢,整套 \(\{\beta_t\}\) 称为噪声调度(noise schedule)。这条更新等价地写成概率形式:
\[ q(z_1|x) = \mathrm{Norm}_{z_1}\!\big[\sqrt{1-\beta_1}\,x,\ \beta_1 I\big] \]
\[ q(z_t|z_{t-1}) = \mathrm{Norm}_{z_t}\!\big[\sqrt{1-\beta_t}\,z_{t-1},\ \beta_t I\big]. \]
这是一条马尔可夫链:\(z_t\) 的概率完全由它前一个变量 \(z_{t-1}\) 决定。步数 \(T\) 足够多时,原始数据的所有痕迹都被抹掉,\(q(z_T|x)=q(z_T)\) 变成标准正态。给定输入 \(x\),所有潜变量的联合分布是:
\[ q(z_{1\dots T}|x) = q(z_1|x)\prod_{t=2}^{T} q(z_t|z_{t-1}). \]
注意命名差异:这里”前向”是从数据走向噪声,与归一化流恰好相反(归一化流里”前向”是从潜变量回到数据)。
18.2.1 扩散核 \(q(z_t|x)\):一步到位的捷径
训练解码器时,我们需要对同一个 \(x\) 在时刻 \(t\) 采很多个 \(z_t\)。若按上面的公式逐步迭代,\(t\) 很大时会非常慢。幸好 \(q(z_t|x)\) 有闭式表达,能直接从 \(x\) 采到 \(z_t\),跳过所有中间变量——这就是扩散核(diffusion kernel)。
把前两步代入合并,并利用”两个独立零均值正态之和,方差直接相加”的性质,可一路推得:
\[ z_t = \sqrt{\alpha_t}\cdot x + \sqrt{1-\alpha_t}\cdot \epsilon,\qquad \alpha_t = \prod_{s=1}^{t}(1-\beta_s), \]
其中 \(\epsilon\) 也是一个标准正态样本。写成概率形式即:
\[ q(z_t|x) = \mathrm{Norm}_{z_t}\!\big[\sqrt{\alpha_t}\,x,\ (1-\alpha_t)I\big]. \]
这条公式是全章的核心。它说明:对任意起点 \(x\),\(z_t\) 都服从一个均值、方差都已知的正态分布——均值随 \(t\) 增大向 0 移动,方差随 \(t\) 增大趋近 1。于是若不关心中间历史,就能一步直接采出 \(z_t\)。当 \(t\) 很大时扩散核就退化成标准正态。
18.2.2 边缘分布 \(q(z_t)\)
边缘分布 \(q(z_t)\) 是:在所有可能的起点 \(x\) 与所有扩散路径下,观察到某个 \(z_t\) 值的概率。借助扩散核可写成:
\[ q(z_t) = \int q(z_t|x)\,Pr(x)\,dx. \]
直觉上:反复从数据分布 \(Pr(x)\) 采样,在每个样本上叠加扩散核 \(q(z_t|x)\),叠出来的就是 \(q(z_t)\)。但因为我们不知道真实数据分布 \(Pr(x)\),所以 \(q(z_t)\) 没有闭式解。
18.2.3 条件分布 \(q(z_{t-1}|z_t)\):反向那一步为什么难
要反演加噪,自然想用贝叶斯公式:
\[ q(z_{t-1}|z_t) = \frac{q(z_t|z_{t-1})\,q(z_{t-1})}{q(z_t)}. \]
可惜这是不可计算的,因为它依赖那个算不出来的边缘分布 \(q(z_{t-1})\)。在简单的一维例子里可以数值地把它画出来:一般情况下它形状复杂、甚至多峰,但很多时候用正态分布就能很好地近似。这一点很关键——正是它让我们敢在解码器里用正态分布去近似反向过程。
18.2.4 条件扩散分布 \(q(z_{t-1}|z_t,x)\):训练时真正用到的目标
上面 \(q(z_{t-1}|z_t)\) 算不出来,是因为不知道 \(q(z_{t-1})\)。但如果额外知道起点 \(x\),那么 \(z_{t-1}\) 在它之前一刻的分布 \(q(z_{t-1}|x)\) 就是扩散核,是正态的、已知的。于是 \(q(z_{t-1}|z_t,x)\) 可以闭式算出——它就是训练解码器时的”标准答案”(毕竟训练时我们当然知道真值 \(x\))。
用贝叶斯公式并配合两个高斯恒等式(高斯换元、两正态相乘合并)化简,得到:
\[ q(z_{t-1}|z_t,x) = \mathrm{Norm}_{z_{t-1}}\!\left[\frac{(1-\alpha_{t-1})\sqrt{1-\beta_t}}{1-\alpha_t}\,z_t + \frac{\sqrt{\alpha_{t-1}}\,\beta_t}{1-\alpha_t}\,x,\ \frac{\beta_t(1-\alpha_{t-1})}{1-\alpha_t}I\right]. \]
它是一个正态分布,均值是 \(z_t\) 与 \(x\) 的加权组合。记住这个均值——它就是后面解码器网络要去拟合的目标。
18.3 解码器(反向去噪过程)
学一个扩散模型,就是学反向过程:从 \(z_T\) 退回 \(z_{T-1}\),再退到 \(z_{T-2}\)……一直退到数据 \(x\)。
真实的反向分布 \(q(z_{t-1}|z_t)\) 是依赖数据分布的复杂多峰分布(见 18.2.3)。我们用正态分布来近似它们:
\[ Pr(z_T) = \mathrm{Norm}_{z_T}[0, I] \]
\[ Pr(z_{t-1}|z_t,\phi_t) = \mathrm{Norm}_{z_{t-1}}\!\big[f_t[z_t,\phi_t],\ \sigma_t^2 I\big] \]
\[ Pr(x|z_1,\phi_1) = \mathrm{Norm}_{x}\!\big[f_1[z_1,\phi_1],\ \sigma_1^2 I\big], \]
其中 \(f_t[z_t,\phi_t]\) 是一个神经网络,负责算出”从 \(z_t\) 退回 \(z_{t-1}\)”这一步正态分布的均值;方差 \(\{\sigma_t^2\}\) 是预先设定的。只要前向的 \(\beta_t\) 足够接近 0(且步数 \(T\) 足够大),这个正态近似就足够好。
采样(生成)用祖先采样(ancestral sampling):先从 \(Pr(z_T)\) 采出 \(z_T\);再从 \(Pr(z_{T-1}|z_T,\phi_T)\) 采 \(z_{T-1}\);从 \(Pr(z_{T-2}|z_{T-1},\phi_{T-1})\) 采 \(z_{T-2}\)……一路到最后从 \(Pr(x|z_1,\phi_1)\) 生成 \(x\)。
直觉图(反向过程):把”墨水扩散”那段视频倒放——从一片均匀的灰,一帧一帧地凝聚、收束,最终重新汇成一滴清晰的墨迹(数据)。网络要学的就是”倒放”中每一帧该怎么算。
18.4 训练
观测变量 \(x\) 与潜变量 \(\{z_t\}\) 的联合分布是:
\[ Pr(x, z_{1\dots T}|\phi_{1\dots T}) = Pr(x|z_1,\phi_1)\prod_{t=2}^{T} Pr(z_{t-1}|z_t,\phi_t)\cdot Pr(z_T). \]
数据似然要对所有潜变量做积分(边缘化)才能得到:
\[ Pr(x|\phi_{1\dots T}) = \int Pr(x,z_{1\dots T}|\phi_{1\dots T})\,dz_{1\dots T}. \]
训练就是最大化训练集的对数似然。但上面这个积分算不出来,所以——和 VAE 一模一样——我们用 Jensen 不等式构造一个下界,转而优化这个下界。
18.4.1 证据下界(ELBO)
把对数似然乘除以编码器分布 \(q(z_{1\dots T}|x)\),再套 Jensen 不等式,得到证据下界(ELBO):
\[ \mathrm{ELBO}[\phi_{1\dots T}] = \int q(z_{1\dots T}|x)\,\log\!\left[\frac{Pr(x,z_{1\dots T}|\phi_{1\dots T})}{q(z_{1\dots T}|x)}\right]dz_{1\dots T}. \]
与 VAE 的关键差别:在 VAE 里,编码器 \(q(z|x)\) 是可学习的,靠它逼近后验来把界”收紧”,解码器再去最大化这个界。但在扩散模型里,编码器没有参数,所以收紧界的活儿全得由解码器来干——它既要让那个被冻结的编码器尽量逼近后验 \(Pr(z_{1\dots T}|x,\phi)\),又要在该界下优化自己的参数。
18.4.2 化简 ELBO
把联合分布和编码器联合分布的定义代入对数项,再用一个技巧——把 \(q(z_t|z_{t-1})\) 用贝叶斯公式改写成
\[ q(z_t|z_{t-1}) = q(z_t|z_{t-1},x) = \frac{q(z_{t-1}|z_t,x)\,q(z_t|x)}{q(z_{t-1}|x)}, \]
代入后,相邻项的 \(q(z_t|x)\) 比值会逐级抵消,只剩首尾两项;而结尾那项 \(\log\!\big[Pr(z_T)/q(z_T|x)\big]\approx\log 1 = 0\)(因为前向终点 \(q(z_T|x)\) 已是标准正态,恰等于先验 \(Pr(z_T)\))。最后化简的 ELBO 是:
\[ \mathrm{ELBO}[\phi_{1\dots T}] \approx \underbrace{\mathbb{E}_{q(z_1|x)}\big[\log Pr(x|z_1,\phi_1)\big]}_{\text{重建项}} - \sum_{t=2}^{T}\mathbb{E}_{q(z_t,z_{t-1}|x)}\Big[D_{KL}\big[q(z_{t-1}|z_t,x)\,\|\,Pr(z_{t-1}|z_t,\phi_t)\big]\Big]. \]
它由两部分组成:
- 重建项:和 VAE 里的重建项对应——模型预测越贴近观测数据,ELBO 越大。
- 一串 KL 散度项:度量”网络给出的反向分布 \(Pr(z_{t-1}|z_t,\phi_t)\)”与”真实的条件扩散分布 \(q(z_{t-1}|z_t,x)\)”(18.2.4 那个闭式正态)之间的距离。
18.4.3 分析 ELBO
两个正态分布之间的 KL 散度有闭式解;而且其中很多项与参数 \(\phi\) 无关。代入 18.2.4 与 18.3 的定义后,KL 项简化为”两个均值之差的平方 + 常数”:
\[ D_{KL}\big[q(z_{t-1}|z_t,x)\,\|\,Pr(z_{t-1}|z_t,\phi_t)\big] = \frac{1}{2\sigma_t^2}\left\|\frac{(1-\alpha_{t-1})\sqrt{1-\beta_t}}{1-\alpha_t}\,z_t + \frac{\sqrt{\alpha_{t-1}}\,\beta_t}{1-\alpha_t}\,x - f_t[z_t,\phi_t]\right\|^2 + C. \]
也就是说,训练目标其实就是让网络的输出 \(f_t[z_t,\phi_t]\) 去逼近那个目标均值(即真实反向分布的均值)。
18.4.4 扩散损失函数
把 ELBO 取负号转成最小化,并用样本近似期望,得到损失:
\[ L[\phi_{1\dots T}] = \sum_{i=1}^{I}\bigg(\underbrace{-\log\mathrm{Norm}_{x_i}\!\big[f_1[z_{i1},\phi_1],\sigma_1^2 I\big]}_{\text{重建项}} + \sum_{t=2}^{T}\frac{1}{2\sigma_t^2}\Big\|\underbrace{\tfrac{1-\alpha_{t-1}}{1-\alpha_t}\sqrt{1-\beta_t}\,z_{it} + \tfrac{\sqrt{\alpha_{t-1}}\beta_t}{1-\alpha_t}\,x_i}_{\text{目标:}q(z_{t-1}|z_t,x)\text{ 的均值}} - \underbrace{f_t[z_{it},\phi_t]}_{\text{预测的 }z_{t-1}}\Big\|^2\bigg). \]
18.4.5 训练过程
这个损失可以为每个时间步训练一个网络:它最小化”网络对上一步隐变量的估计 \(f_t[z_t,\phi_t]\)”与”在已知真值去噪数据 \(x\) 时它最可能取的值”之间的差。具体做法:(i) 从原始分布取一大批样本 \(x\);(ii) 用扩散核为每个 \(x\) 在各时刻 \(t\) 采出对应的 \(z_t\);(iii) 训练网络 \(f_t\) 去最小化上面的损失。
18.5 损失函数的重参数化
上面的损失能用,但实践中发现:换一种参数化会让扩散模型表现明显更好——让网络不再去预测”上一步的隐变量”,而是去预测”混进当前变量里的那团噪声”。这一节分两步重写:先重写目标,再重写网络。
18.5.1 重参数化目标
由扩散核 \(z_t=\sqrt{\alpha_t}\,x+\sqrt{1-\alpha_t}\,\epsilon\) 反解出数据项:
\[ x = \frac{1}{\sqrt{\alpha_t}}\cdot z_t - \frac{\sqrt{1-\alpha_t}}{\sqrt{\alpha_t}}\cdot \epsilon. \]
把它代回损失里的目标均值,并用恒等式 \(\sqrt{\alpha_t}/\sqrt{\alpha_{t-1}}=\sqrt{1-\beta_t}\) 反复化简,那个看起来很吓人的目标均值会坍缩成一个干净的形式:
\[ \frac{(1-\alpha_{t-1})\sqrt{1-\beta_t}}{1-\alpha_t}\,z_t + \frac{\sqrt{\alpha_{t-1}}\,\beta_t}{1-\alpha_t}\,x = \frac{1}{\sqrt{1-\beta_t}}\,z_t - \frac{\beta_t}{\sqrt{1-\alpha_t}\sqrt{1-\beta_t}}\,\epsilon. \]
也就是说,目标均值可以只用 \(z_t\) 和噪声 \(\epsilon\) 来表达。
18.5.2 重参数化网络
既然目标里只剩 \(z_t\) 和 \(\epsilon\),那干脆让网络也直接去预测噪声。把原来的均值网络 \(\hat z_{t-1}=f_t[z_t,\phi_t]\) 替换成一个噪声预测网络 \(\hat\epsilon = g_t[z_t,\phi_t]\),二者关系为:
\[ f_t[z_t,\phi_t] = \frac{1}{\sqrt{1-\beta_t}}\,z_t - \frac{\beta_t}{\sqrt{1-\alpha_t}\sqrt{1-\beta_t}}\,g_t[z_t,\phi_t]. \]
代回去后,目标里那一堆 \(z_t\) 项自动抵消,损失变成一个纯粹的”噪声预测误差”:
\[ L[\phi_{1\dots T}] = \sum_{i=1}^{I}\sum_{t=1}^{T}\frac{\beta_t^2}{(1-\alpha_t)(1-\beta_t)2\sigma_t^2}\,\big\|g_t[z_{it},\phi_t] - \epsilon_{it}\big\|^2. \]
实践中干脆把每个时间步前面那个复杂的缩放系数全部忽略,得到一个极简版本:
\[ L[\phi_{1\dots T}] = \sum_{i=1}^{I}\sum_{t=1}^{T}\big\|g_t[z_{it},\phi_t] - \epsilon_{it}\big\|^2 = \sum_{i=1}^{I}\sum_{t=1}^{T}\big\|g_t\big[\sqrt{\alpha_t}\,x_i + \sqrt{1-\alpha_t}\,\epsilon_{it},\ \phi_t\big] - \epsilon_{it}\big\|^2. \]
第二个等号用扩散核把 \(z_t\) 展开了。整章绕了一大圈,最终目标就是这句话:给网络喂一张带噪图 \(z_t=\sqrt{\alpha_t}\,x+\sqrt{1-\alpha_t}\,\epsilon\),让它把混进去的噪声 \(\epsilon\) 预测出来,最小化 \(\|\epsilon-g_t[z_t,\phi_t]\|^2\)。简单、稳定、好训练。
18.6 实现(含条件生成与 Stable Diffusion 思想)
重参数化后,训练和采样都变得很直接:
训练算法(算法 18.1):循环——对批中每个样本,
- 随机采时间步 \(t\sim\mathrm{Uniform}[1,\dots,T]\);
- 采噪声 \(\epsilon\sim\mathrm{Norm}[0,I]\);
- 计算单样本损失 \(\ell_i = \big\|g_t[\sqrt{\alpha_t}\,x_i + \sqrt{1-\alpha_t}\,\epsilon,\ \phi_t] - \epsilon\big\|^2\);
- 累积整批损失并做一步梯度下降,直到收敛。
这套训练有两大优点:(i) 实现简单;(ii) 天然做数据增强——每个原始样本 \(x_i\) 可在每个时间步用不同噪声 \(\epsilon\) 反复利用无数次。
采样算法(算法 18.2):
- 采最后一个潜变量 \(z_T\sim\mathrm{Norm}[0,I]\);
- 对 \(t=T,\dots,2\):先用噪声预测网络算出去噪估计 \(\hat z_{t-1}=\frac{1}{\sqrt{1-\beta_t}}\,z_t - \frac{\beta_t}{\sqrt{1-\alpha_t}\sqrt{1-\beta_t}}\,g_t[z_t,\phi_t]\),再采新噪声 \(\epsilon\sim\mathrm{Norm}[0,I]\),令 \(z_{t-1}=\hat z_{t-1}+\sigma_t\epsilon\);
- 最后从 \(z_1\) 不加噪声地生成 \(x\)。
采样的缺点是:必须串行地跑很多个网络 \(g_t\),因此很耗时。
18.6.1 应用于图像
扩散模型在图像上极为成功。这里网络要做的是”看带噪图、预测加进去的噪声”,是一个图到图映射,最自然的架构就是 U-Net。但扩散步数可能很多,为每步存一个 U-Net 太浪费。解决办法是:训练一个共享的 U-Net,把代表时间步的向量也作为输入(通常先把时间步过一个正弦位置编码再过一个浅网络,然后在 U-Net 各阶段的每个空间位置上做偏移/缩放)。U-Net 内部由残差块和周期性的全局自注意力连接组成。
为什么要很多步?因为只有当 \(\beta_t\) 接近 0 时,反向条件分布 \(q(z_{t-1}|z_t)\) 才足够接近正态,从而匹配解码器的正态假设。代价是采样慢——可能要跑 \(T=1000\) 步才能生成好图。
18.6.2 提升生成速度
极简损失只要求扩散核满足 \(q(z_t|x)=\mathrm{Norm}[\sqrt{\alpha_t}\,x,(1-\alpha_t)I]\) 这一关系。满足该关系的前向过程其实有一整族,它们都被同一个损失优化,但前向规则和对应的反向规则各不相同。其中两个重要成员:
- 去噪扩散隐式模型(DDIM):从 \(x\) 到 \(z_1\) 之后不再随机(确定性),等价于把模型变成一个低曲率的常微分方程,可用高效数值解法。
- 加速采样模型:前向过程只定义在时间步的一个子序列上,于是反向可以跳步,采样快得多。当过程变确定性后,约 50 步就能出好图——比原来快很多,但仍慢于多数其他生成模型。
18.6.3 条件生成
如果数据带标签 \(c\),就能用它来控制生成(知道图里大概有什么,去噪会更容易)。
-
分类器引导(classifier guidance):在采样的更新步里加一项,依赖一个基于潜变量的分类器 \(Pr(c|z_t)\) 的梯度: \[ z_{t-1} = \hat z_{t-1} + \sigma_t^2\,\frac{\partial \log Pr(c|z_t)}{\partial z_t} + \sigma_t\epsilon. \] 这一项把更新”推向”让类别 \(c\) 更可能的方向。缺点是要额外训练一个分类器,代价不小。
-
无分类器引导(classifier-free guidance):不再训练单独的分类器,而是把类别信息直接喂进主网络 \(g_t[z_t,\phi_t,c]\)(通常和时间步一样,把 \(c\) 的嵌入加到 U-Net 各层)。训练时随机丢弃一部分类别信息,让同一个模型同时学会条件生成和无条件生成。测试时它既能无条件、也能有条件生成,还能按任意权重把两者混合。一个有趣的副作用:过度加权条件信息时,模型会产出质量极高但略显”刻板/典型化”的样本——这与 GAN 里的截断技巧异曲同工。
18.6.4 提升生成质量与文生图
最高质量的结果来自一系列技巧的叠加:
- 同时估计方差:除了均值,也学习反向过程的方差 \(\sigma_t^2\),在少步采样时尤其有帮助;
- 调整噪声调度:让 \(\beta_t\) 在不同步上变化,可改善效果;
- 级联(cascade)生成高分辨率:先用一个扩散模型生成低分辨率图(可由类别引导),后续扩散模型逐级生成更高分辨率,每一级都以上一级的低分图为条件(把它缩放后拼接进 U-Net 各层)。
文生图(如 Imagen 思想):把文本提示用一个语言模型(如 BERT)编码成句嵌入,再像时间步那样注入 U-Net;配合上面的级联,就能从一句话生成 64×64 → 256×256 → 1024×1024 的逼真图像,且与描述吻合。由于模型本身是随机的,同一句提示可生成多张不同的合理图像。
Stable Diffusion 思想(提速的另一条路):先用一个常规自编码器把原始数据压到更小的潜空间,再在这个小空间里跑扩散过程。好处是:(i) 大幅降低扩散过程要处理的维度,省时省算;(ii) 让文本、图等其它数据类型也能纳入同一框架。这是当今主流文生图系统兼顾质量与速度的关键思路。
本章小结
扩散模型把数据样本经过一串潜变量,靠”反复把当前表示与随机噪声相掺”逐步推进;足够多步以后,表示变得与白噪声无异。由于每步改动很小,反向去噪的每一步都能用一个正态分布近似,并由深度网络预测。损失函数源自证据下界(ELBO),最终落到一个极简的最小二乘式——本质就是”预测噪声”\(\|\epsilon-g_t[z_t,\phi_t]\|^2\)。
图像生成中每个去噪步用 U-Net 实现,因此采样比其它生成模型慢。提速可改用确定性形式(如 DDIM),少步采样也能工作良好。围绕类别、图像、文本的多种条件生成方法(分类器引导、无分类器引导、级联、潜空间扩散)相互组合,造就了今天令人惊艳的文生图效果。扩散模型可视作编码器被冻结、潜空间与数据同维的分层 VAE:训练简单、样本质量高,但缺点是采样慢且潜空间没有语义可解释性。
关键术语对照
| 中文 | English | 一句话含义 |
|---|---|---|
| 前向 / 扩散过程 | Forward / diffusion process | 预设的、逐步加噪把数据变成纯噪声 |
| 反向过程 | Reverse process | 学出来的、逐步去噪重建数据 |
| 噪声调度 | Noise schedule | 一串超参数 \(\beta_t\),决定每步加噪的快慢 |
| 扩散核 | Diffusion kernel | 一步直接采到 \(z_t\) 的闭式公式 \(q(z_t|x)\) |
| 边缘分布 | Marginal distribution | 综合所有起点与路径后 \(z_t\) 的分布 |
| 马尔可夫链 | Markov chain | 当前状态只由前一状态决定 |
| 证据下界 | ELBO | 对数似然的下界,扩散模型的训练目标来源 |
| KL 散度 | KL divergence | 衡量两个分布的差距 |
| 重参数化 | Reparameterization | 把目标从”预测隐变量”改为”预测噪声” |
| 噪声预测网络 | Noise prediction network | \(g_t[z_t,\phi_t]\),预测混进 \(z_t\) 的噪声 |
| 祖先采样 | Ancestral sampling | 从 \(z_T\) 逐步采到 \(x\) 的生成流程 |
| U-Net | U-Net | 图像扩散常用的图到图骨干网络 |
| DDIM | Denoising diffusion implicit model | 确定性、可跳步的快速采样变体 |
| 分类器引导 | Classifier guidance | 用分类器梯度把生成推向目标类别 |
| 无分类器引导 | Classifier-free guidance | 不另训分类器,主模型兼学条件/无条件 |
| 级联生成 | Cascaded generation | 由低到高分辨率逐级条件生成 |
| 潜空间扩散 | Latent diffusion (Stable Diffusion) | 先压到小潜空间再扩散,提速且通用 |
返回目录 | 上一章:第 17 章 变分自编码器 | 下一章:第 19 章 强化学习