Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

扩散模型

目录

  • 去噪扩散概率模型

  • 扩散模型改进

  • 隐扩散模型

  • 扩散模型实例

  • 典型扩散模型

去噪扩散概率模型概述

生成模型前景

生成模型前景

样本密度分布建模

假设所有样本都来自分布 pdata(x)p_{data}(x)

  • 生成机器学习模型的目标是尽其所能地学习样本分布——模型近似的分布表示为 pθ(x)p_\theta(x)

  • 我们通过从学习到的分布中采样来生成新样本

  • 通常训练模型以最大化 pθ(x)p_\theta(x) 的期望对数似然(或最小化负对数似然)/最小化 pθ(x)p_\theta(x)pdata(x)p_{data}(x) 之间的散度(divergence)

现有生成模型方法:VAE与GAN

VAE:

LVAE(θ,ϕ)=logpθ(x)+DKL(qϕ(zx)pθ(zx))=Ezqϕ(zx)logpθ(xz)+DKL(qϕ(zx)pθ(z))θ,ϕ=argminθ,ϕLVAELVAE=logpθ(x)DKL(qϕ(zx)pθ(zx))logpθ(x)\begin{aligned} L_{\mathrm{VAE}}(\theta, \phi) & =-\log p_\theta(\mathbf{x})+D_{\mathrm{KL}}\left(q_\phi(\mathbf{z} \mid \mathbf{x}) \| p_\theta(\mathbf{z} \mid \mathbf{x})\right) \\ & =-\mathbb{E}_{\mathbf{z} \sim q_\phi(\mathbf{z} \mid \mathbf{x})} \log p_\theta(\mathbf{x} \mid \mathbf{z})+D_{\mathrm{KL}}\left(q_\phi(\mathbf{z} \mid \mathbf{x}) \| p_\theta(\mathbf{z})\right) \\ \theta^*, \phi^* & =\arg \min _{\theta, \phi} L_{\mathrm{VAE}} \\ -L_{\mathrm{VAE}} & =\log p_\theta(\mathbf{x})-D_{\mathrm{KL}}\left(q_\phi(\mathbf{z} \mid \mathbf{x}) \| p_\theta(\mathbf{z} \mid \mathbf{x})\right) \leq \log p_\theta(\mathbf{x}) \end{aligned}

GAN:

minGmaxDL(D,G)=Expr(x)[logD(x)]+Ezpz(z)[log(1D(G(z)))]=Expr(x)[logD(x)]+Expg(x)[log(1D(x))]\begin{aligned} \min _G \max _D L(D, G) & =\mathbb{E}_{x \sim p_r(x)}[\log D(x)]+\mathbb{E}_{z \sim p_z(z)}[\log (1-D(G(z)))] \\ & =\mathbb{E}_{x \sim p_r(x)}[\log D(x)]+\mathbb{E}_{x \sim p_g(x)}[\log (1-D(x))] \end{aligned}

数学上可以证明,训练 GAN 等价于最小化真实数据和生成数据之间的 Jensen-Shannon 散度。当生成器完美时(pg=prp_g = p_r),散度为 0,损失达到其全局最小值 2log2-2\log2

L(G,D)=2DJS(prpg)2log2L(G,D^*) = 2D_{JS}(p_r||p_g)- 2\log{2}

生成模型的挑战与对比

扩散模型的物理原理与设计思想

  • 扩散作用是一个基于分子热运动的运输现象,是分子通过布朗运动从高浓度区域 (或 高化势) 向低浓度区域 (或低化势) 的运输的过程。它是趋向于热平衡态的弛豫过程。 菲克定律 (Fick’s laws) 是扩散作用的近似描述,实际过程是从高化势区域向低化势区域的转移。扩散作用的速率和混合物的浓度梯度一般不太大,因此通常可以用近平衡态热力学理论进行处理。

  • 扩散模型的灵感来自非平衡热力学。它提出了一种以小步长迭代地将马尔可夫链的输出视为模型对学习分布的近似 ,以缓慢地将随机噪声添加到样本中,然后学习逆向扩散过程,从而根据噪声构建所需的数据样本。

  • 与 VAE 或流模型不同,扩散模型是通过固定程序学习的,并且隐变量具有高维度(与原始样本 相同)。

去噪扩散概率模型机制

去噪扩散概率模型 ( Denoising Diffusion Probabilistic Models , DDPM )的机制

  • 正向过程用于生成建模,通过逐步添加高斯噪声将样本(如图像、文本)降级至类似随机噪声状态。数学上,每一步由高斯转换内核定义,按预定方差增加噪声。随着噪声增加,样本结构减少,趋近纯噪声。此过程旨在构建从原始样本到简单先验分布的映射,以支持逆向的去噪和重建过程。

  • 逆向过程利用神经网络从噪声中逐步去噪以重建样本,模拟正向过程的逆向操作。神经网络学习去除噪声分量,通过分数匹配 (Score Matching) 或变分推理等技术优化输出。逆向迭代去噪步骤生成高质量样本,使模型能将噪声转化为连贯结构化的输出,极大增强了生成模型的能力。

正向扩散过程

  • 给定初始的样本分布 x0q(x0)x_0 \sim q(x_0) ,在扩散过程中不断添加高斯噪声,随着 t 不断的增大,会生成一序列添加噪声的样本, x1,x2,,xTx_1, x_2, \dots, x_T

  • 步长由方差调度超参数 βt[0,1)\beta_t \in [0, 1) 确定

  • 重复这个过程 TT 个步骤 —— 随着时间步骤的增加,原始输入的更多特征会变得无法识别

  • TT 接近无穷大时,您最终会得到各向同性高斯(即纯随机噪声)

  • 转移概率 (transition probability) q(xtxt1)=N(xt;1βtxt1,βtI)q(\mathbf{x}_t | \mathbf{x}_{t-1}) = \mathcal{N}(\mathbf{x}_t; \sqrt{1-\beta_t}\mathbf{x}_{t-1}, \beta_t \mathbf{I}), q(x1:T|x0)=t=1Tq(xt|xt1)q\left(\mathbf{x}_{1:T}\middle|\mathbf{x}_0\right)=\prod_{t=1}^{T}{q\left(\mathbf{x}_t\middle|\mathbf{x}_{t-1}\right)}

重新参数化技巧

上述过程有一个很好的特性是我们可以在任意时间步对 xt\mathbf{x}_t 以闭式进行重参数化采样。令 αt=1βt\alpha_t=1-\beta_tαt=i=1tαi{\overline{\alpha}}_t=\prod_{i=1}^{t}\alpha_i

q(xtxt1)=N(xt;1βtxt1,βtI)xt=αtxt1+1αtϵt1where ϵt1,ϵt2,N(0,I)=αtαt1xt2+1αtαt1ϵt2where ϵt2 merges two Gaussians.==αˉtx0+1αˉtϵq(xtx0)=N(xt;αˉtx0,(1αˉt)I)\begin{align} q(\mathbf{x}_t|\mathbf{x}_{t-1}) &= \mathcal{N}(\mathbf{x}_t; \sqrt{1-\beta_t}\mathbf{x}_{t-1}, \beta_t \mathbf{I}) \\ \mathbf{x}_t &= \sqrt{\alpha_t}\mathbf{x}_{t-1} + \sqrt{1-\alpha_t}\boldsymbol{\epsilon}_{t-1} \quad \text{where } \boldsymbol{\epsilon}_{t-1}, \boldsymbol{\epsilon}_{t-2}, \cdots \sim \mathcal{N}(\mathbf{0}, \mathbf{I}) \\ &= \sqrt{\alpha_t\alpha_{t-1}}\mathbf{x}_{t-2} + \sqrt{1-\alpha_t\alpha_{t-1}}\boldsymbol{\epsilon}_{t-2} \quad \text{where } \boldsymbol{\epsilon}_{t-2} \text{ merges two Gaussians.} \\ &= \cdots \\ &= \color{blue}{\sqrt{\bar{\alpha}_t}\mathbf{x}_0 + \sqrt{1-\bar{\alpha}_t}\boldsymbol{\epsilon}} \\ \color{red}{q(\mathbf{x}_t|\mathbf{x}_0)} &= \color{red}{\mathcal{N}(\mathbf{x}_t; \sqrt{\bar{\alpha}_t}\mathbf{x}_0, (1-\bar{\alpha}_t)\mathbf{I})} \end{align}
  • 任意时刻的 q(xt)q\left(\mathbf{x}_t\right) 也可以完全基于 x0\mathbf{x}_0βt\beta_t 来计算出来,而不需要做迭代

  • 根据正态分布的叠加性:两个正态分布 XN(μ1,σ12)X\sim \mathcal{N}\left(\mu_1,\sigma_1^2\right)YN(μ2,σ22)Y\sim \mathcal{N}\left(\mu_2,\sigma_2^2\right),aX+bYaX+bY 的叠加就是均值为 aμ1+bμ2a\mu_1+b\mu_2, 方差为 a2σ12+b2σ22a^2\sigma_1^2+b^2\sigma_2^2 的正态分布;

  • 叠加后的标准方差为 σ=(1αt)+αt(1αt1)=1αtαt1\sigma=\sqrt{(1-\alpha_t)+\alpha_t(1-\alpha_{t-1})}=\sqrt{1-\alpha_t\alpha_{t-1}}

αt=1βt\alpha_t = 1 - \beta_t,并定义 αt=i=1tαi{\overline{\alpha}}_t = \prod_{i=1}^t \alpha_i,则有 xt=αtx0+1αtϵ\mathbf{x}_t = \sqrt{{\overline{\alpha}}_t}\mathbf{x}_0 + \sqrt{1-{\overline{\alpha}}_t}\boldsymbol{\epsilon}。 通过选取适当的超参数 αt\alpha_t,使得 αt\alpha_t 递减并趋近于 0,此时 βt\beta_t 趋近于 1。经过 TT 步后,原样本将近似扩散为各向同性高斯分布。例如,设 αt\alpha_t 为单调递减序列,如 αt=10.02tT\alpha_t = \sqrt{1-\frac{0.02t}{T}}

计算 logαT\log \alpha_T:若 t=Tt = T

logαT=12log(10.02TT)=12log(0.98)\log \alpha_T = \frac{1}{2}\log\left(1-\frac{0.02T}{T}\right) = \frac{1}{2}\log(0.98)

根据泰勒展开,对于 0<x<10 < x < 1log(1x)<x\log(1-x) < -x,因此:

logαt=12log(10.02tT)<0.01tT\log \alpha_t = \frac{1}{2}\log\left(1-\frac{0.02t}{T}\right) < -\frac{0.01 t}{T}

所以当 T=1000T=1000 时,αTe50\alpha_T \approx e^{-5} \approx 0,此时 xT=αTx0+1αTϵϵN(0,I)\mathbf{x}_T = \sqrt{{\overline{\alpha}}_T}\mathbf{x}_0 + \sqrt{1-{\overline{\alpha}}_T}\boldsymbol{\epsilon} \approx \boldsymbol{\epsilon} \sim \mathcal{N}(0, I)

逆向过程

如果能够逆正向过程,并从 q(xt1xt)q(\mathbf{x}_{t-1}|\mathbf{x}_t) 中采样,那么就可以从高斯噪声输入 xTN(0,I)\mathbf{x}_T\sim\mathcal{N}(\mathbf{0},\mathbf{I}) 重新创建真实样本。如果 βt\beta_t 足够小,q(xt1xt)q(\mathbf{x}_{t-1}|\mathbf{x}_t) 也将是高斯的。但是估计 q(xt1|xt)q\left(\mathbf{x}_{t-1}\middle|\mathbf{x}_t\right) 需要使用整个数据集,因此我们需要学习一个模型 pθp_\theta 来近似这些条件概率以便进行逆向扩散过程。从各项独立的高斯分布中恢复原始样本,假设它也是一个高斯分布,但是逆扩散无法逐步拟合分布,所以需要构建一个参数分布来做估计。

pθ(x0:T)=p(xT)t=1Tpθ(xt1|xt)pθ(xt1xt)=N(xt1;μθ(xt,t),Σθ(xt,t))\begin{align} p_\theta\left(\mathbf{x}_{0:T}\right) &= p\left(\mathbf{x}_T\right)\prod_{t=1}^{T}{p_\theta\left(\mathbf{x}_{t-1}\middle|\mathbf{x}_t\right)} \\ p_\theta(\mathbf{x}_{t-1}|\mathbf{x}_t) &= \mathcal{N}(\mathbf{x}_{t-1};\color{blue}{\boldsymbol{\mu}_\theta(\mathbf{x}_t,t),\boldsymbol{\Sigma}_\theta(\mathbf{x}_t,t)}) \end{align}

扩散模型的目标是学习逆向降噪过程,以迭代地去除正向过程中添加的噪声,逆过程也可以理解为从随机噪声中生成新样本,\color{blue}{\text{以}} x0\color{blue}{\mathbf{x}_0} 已知为条件时,逆向条件概率\color{blue}{\text{已知为条件时,逆向条件概率}} q(xt1|xt,x0)\color{blue}{q\left(\mathbf{x}_{t-1}\middle|\mathbf{x}_t,\mathbf{x}_0\right)} 是可解的。\color{blue}{\text{是可解的。}}

q(xt1|xt,x0)=N(xt1;μ~(xt,x0),β~tI)q\left(\mathbf{x}_{t-1}\middle|\mathbf{x}_t,\mathbf{x}_0\right)=\mathcal{N}\left(\mathbf{x}_{t-1};\color{blue}{\tilde{\boldsymbol{\mu}}\left(\mathbf{x}_t,\mathbf{x}_0\right),\tilde{\beta}_t\mathbf{I}}\right)

根据联合概率公式:

q(xt1|xt,x0)q(xt|x0)=q(xt,xt1|x0)=q(xt|xt1,x0)q(xt1|x0)q\left(\mathbf{x}_{t-1}\middle|\mathbf{x}_t,\mathbf{x}_0\right)q\left(\mathbf{x}_t\middle|\mathbf{x}_0\right)=q\left(\mathbf{x}_t,\mathbf{x}_{t-1}\middle|\mathbf{x}_0\right)=q\left(\mathbf{x}_t\middle|\mathbf{x}_{t-1},\mathbf{x}_0\right)q\left(\mathbf{x}_{t-1}\middle|\mathbf{x}_0\right)

我们有:

q(xt1|xt,x0)=q(xt|xt1,x0)q(xt1|x0)q(xt|x0)\begin{align} q\left(\mathbf{x}_{t-1}\middle|\mathbf{x}_t,\mathbf{x}_0\right) &= q\left(\mathbf{x}_t\middle|\mathbf{x}_{t-1},\mathbf{x}_0\right)\frac{q\left(\mathbf{x}_{t-1}\middle|\mathbf{x}_0\right)}{q\left(\mathbf{x}_t\middle|\mathbf{x}_0\right)} \end{align}

因为正向过程是马尔科夫链,xt\mathbf{x}_t 只依赖于邻接时刻 xt1\mathbf{x}_{t-1},所以:

q(xt|xt1,x0)=q(xt|xt1)q\left(\mathbf{x}_t\middle|\mathbf{x}_{t-1},\mathbf{x}_0\right)=q\left(\mathbf{x}_t\middle|\mathbf{x}_{t-1}\right)

代入上式得:

q(xt1|xt,x0)=q(xt|xt1)q(xt1|x0)q(xt|x0)\begin{align} q\left(\mathbf{x}_{t-1}\middle|\mathbf{x}_t,\mathbf{x}_0\right) &= q\left(\mathbf{x}_t\middle|\mathbf{x}_{t-1}\right)\frac{q\left(\mathbf{x}_{t-1}\middle|\mathbf{x}_0\right)}{q\left(\mathbf{x}_t\middle|\mathbf{x}_0\right)} \end{align}

根据前向过程的定义,我们有:

q(xt|xt1)=N(xt;1βtxt1,βtI)q\left(\mathbf{x}_t\middle|\mathbf{x}_{t-1}\right)=\mathcal{N}\left(\mathbf{x}_t;\sqrt{1-\beta_t}\mathbf{x}_{t-1},\beta_t\mathbf{I}\right)

q(xtx0)=N(xt;αˉtx0,(1αˉt)I)q(\mathbf{x}_t|\mathbf{x}_0)=\mathcal{N}\left(\mathbf{x}_t;\sqrt{\bar{\alpha}_t}\mathbf{x}_0,\left(1-\bar{\alpha}_t\right)\mathbf{I}\right)

将以上高斯分布代入,得到:

q(xt1|xt,x0)=N(xt;1βtxt1,βtI)N(xt1;αˉt1x0,(1αˉt1)I)N(xt;αˉtx0,(1αˉt)I)\begin{align} q\left(\mathbf{x}_{t-1}\middle|\mathbf{x}_t,\mathbf{x}_0\right) &= \mathcal{N}\left(\mathbf{x}_t;\sqrt{1-\beta_t}\mathbf{x}_{t-1},\beta_t\mathbf{I}\right)\frac{\mathcal{N}\left(\mathbf{x}_{t-1};\sqrt{\bar{\alpha}_{t-1}}\mathbf{x}_0,\left(1-\bar{\alpha}_{t-1}\right)\mathbf{I}\right)}{\mathcal{N}\left(\mathbf{x}_t;\sqrt{\bar{\alpha}_t}\mathbf{x}_0,\left(1-\bar{\alpha}_t\right)\mathbf{I}\right)} \end{align}

将各项代入高斯分布的概率密度函数 f(x)=12πσe(xμ)2σ2f(x)=\frac{1}{\sqrt{2\pi\sigma}}e^{-\frac{(x-\mu)^2}{\sigma^2}} 得到各自的概率密度函数:

q(xt1|xt,x0)=N(xt;1βtxt1,βtI)N(xt1;αˉt1x0,(1αˉt1)I)N(xt;αˉtx0,(1αˉt)I)exp(12((xtαtxt1)2βt+(xt1αˉt1x0)21αˉt1(xtαˉtx0)21αˉt))=exp(12(xt22αtxtxt1+αtxt12βt+xt122αˉt1x0xt1+αˉt1x021αˉt1(xtαˉtx0)21αˉt))=exp(12((αtβt+11αˉt1)xt12(2αtβtxt+2αˉt11αˉt1x0)xt1+C(xt,x0)))\begin{align} q\left(\mathbf{x}_{t-1}\middle|\mathbf{x}_t,\mathbf{x}_0\right) &= \mathcal{N}\left(\mathbf{x}_t;\sqrt{1-\beta_t}\mathbf{x}_{t-1},\beta_t\mathbf{I}\right)\frac{\mathcal{N}\left(\mathbf{x}_{t-1};\sqrt{\bar{\alpha}_{t-1}}\mathbf{x}_0,\left(1-\bar{\alpha}_{t-1}\right)\mathbf{I}\right)}{\mathcal{N}\left(\mathbf{x}_t;\sqrt{\bar{\alpha}_t}\mathbf{x}_0,\left(1-\bar{\alpha}_t\right)\mathbf{I}\right)} \\ &\propto\exp{\left(-\frac{1}{2}\left(\frac{(\mathbf{x}_t-\sqrt{\alpha_t}\mathbf{x}_{t-1})^2}{\beta_t}+\frac{(\mathbf{x}_{t-1}-\sqrt{\bar{\alpha}_{t-1}}\mathbf{x}_0)^2}{1-\bar{\alpha}_{t-1}}-\frac{(\mathbf{x}_t-\sqrt{\bar{\alpha}_t}\mathbf{x}_0)^2}{1-\bar{\alpha}_t}\right)\right)} \\ &= \exp\left(-\frac{1}{2}\left(\frac{\mathbf{x}_t^2-2\sqrt{\alpha_t}\mathbf{x}_t\mathbf{x}_{t-1}+\alpha_t\mathbf{x}_{t-1}^2}{\beta_t}+\frac{\mathbf{x}_{t-1}^2-2\sqrt{\bar{\alpha}_{t-1}}\mathbf{x}_0\mathbf{x}_{t-1}+\bar{\alpha}_{t-1}\mathbf{x}_0^2}{1-\bar{\alpha}_{t-1}}-\frac{(\mathbf{x}_t-\sqrt{\bar{\alpha}_t}\mathbf{x}_0)^2}{1-\bar{\alpha}_t}\right)\right) \\ &= \exp\left(-\frac{1}{2}\left(\left(\frac{\alpha_t}{\beta_t}+\frac{1}{1-\bar{\alpha}_{t-1}}\right)\mathbf{x}_{t-1}^2-\left(\frac{2\sqrt{\alpha_t}}{\beta_t}\mathbf{x}_t+\frac{2\sqrt{\bar{\alpha}_{t-1}}}{1-\bar{\alpha}_{t-1}}\mathbf{x}_0\right)\mathbf{x}_{t-1}+C\left(\mathbf{x}_t,\mathbf{x}_0\right)\right)\right) \end{align}

其中 C(xt,x0)C(\mathbf{x}_t,\mathbf{x}_0) 是某函数不含变量 xt1\mathbf{x}_{t-1}

多元高斯分布可以表达为 exp(12xTAx+bTx+c)\exp{\left(-\frac{1}{2}\mathbf{x}^TA\mathbf{x}+b^T\mathbf{x}+c\right)} 一般形式,其中 Σ=A1\mathbf{\Sigma}=A^{-1},均值 μ=A1b\boldsymbol{\mu}=A^{-1}b:

exp(12((αtβt+11αˉt1)xt12(2αtβtxt+2αˉt11αˉt1x0)xt1+C(xt,x0)))\exp\left(-\frac{1}{2}\left(\left(\frac{\alpha_t}{\beta_t}+\frac{1}{1-\bar{\alpha}_{t-1}}\right)\mathbf{x}_{t-1}^2-\left(\frac{2\sqrt{\alpha_t}}{\beta_t}\mathbf{x}_t+\frac{2\sqrt{\bar{\alpha}_{t-1}}}{1-\bar{\alpha}_{t-1}}\mathbf{x}_0\right)\mathbf{x}_{t-1}+C\left(\mathbf{x}_t,\mathbf{x}_0\right)\right)\right)
β~t=Σ=A1=1αtβt+11αˉt1=1αˉt11αˉtβt\tilde{\beta}_t=\mathbf{\Sigma}=A^{-1}=\frac{1}{\frac{\alpha_t}{\beta_t}+\frac{1}{1-\bar{\alpha}_{t-1}}}=\frac{1-\bar{\alpha}_{t-1}}{1-\bar{\alpha}_t}\cdot\beta_t
μ~t(xt,x0)=A1b=αt(1αˉt1)1αˉtxt+αˉt1βt1αˉtx0\tilde{\boldsymbol{\mu}}_t\left(\mathbf{x}_t,\mathbf{x}_0\right)=A^{-1}b=\frac{\sqrt{\alpha_t}(1-\bar{\alpha}_{t-1})}{1-\bar{\alpha}_t}\mathbf{x}_t+\frac{\sqrt{\bar{\alpha}_{t-1}}\beta_t}{1-\bar{\alpha}_t}\mathbf{x}_0

因为 xt=αˉtx0+1αˉtϵx0=1αˉt(xt1αˉtϵt)\mathbf{x}_t=\sqrt{\bar{\alpha}_t}\mathbf{x}_0+\sqrt{1-\bar{\alpha}_t}\boldsymbol{\epsilon} \Rightarrow \mathbf{x}_0=\frac{1}{\sqrt{\bar{\alpha}_t}}(\mathbf{x}_t-\sqrt{1-\bar{\alpha}_t}\boldsymbol{\epsilon}_t)

μ~t=1αt(xt1αt1αˉtϵt)\tilde{\boldsymbol{\mu}}_t=\frac{1}{\sqrt{\alpha_t}}(\mathbf{x}_t-\frac{1-\alpha_t}{\sqrt{1-\bar{\alpha}_t}}\boldsymbol{\epsilon}_t)

最后的表达式就为:

q(xt1|xt,x0)=N(xt1;μ~t,β~tI)=N(xt1;1αt(xt1αt1αˉtϵt),1αˉt11αˉtβtI)q\left(\mathbf{x}_{t-1}\middle|\mathbf{x}_t,\mathbf{x}_0\right)=\mathcal{N}\left(\mathbf{x}_{t-1};\color{blue}{\tilde{\boldsymbol{\mu}}_t,\tilde{\beta}_t\mathbf{I}} \right)=\mathcal{N}\left(\mathbf{x}_{t-1};\frac{1}{\sqrt{\alpha_t}}(\mathbf{x}_t-\frac{1-\alpha_t}{\sqrt{1-\bar{\alpha}_t}}\boldsymbol{\epsilon}_t),\frac{1-\bar{\alpha}_{t-1}}{1-\bar{\alpha}_t}\cdot\beta_t\mathbf{I}\right)

损失函数与变分下界

目标是学习 μ~(xt,x0)\tilde{\boldsymbol{\mu}}\left(\mathbf{x}_t,\mathbf{x}_0\right)β~t\tilde{\beta}_t,类似变分编码器,我们可以利用变分推断中的证据下界ELBO.在真实样本分布下,最大化模型预测分布的期望对数似然,即最小化交叉熵

H(q(x0),pθ(x0))=q(x0)logpθ(x0)dx0=Eq(x0)logpθ(x0)=Eq(x0)log(pθ(x0:T)dx1:T)=Eq(x0)log(q(x1:T|x0)pθ(x0:T)q(x1:T|x0)dx1:T)=Eq(x0)log(Eq(x1:T|x0)pθ(x0:T)q(x1:T|x0))\begin{align} H\left(q\left(x_0\right),p_\theta\left(x_0\right)\right) &= -\int{q\left(x_0\right)\log{p_\theta\left(x_0\right)}dx_0} \\ &= -\mathbb{E}_{q\left(\mathbf{x}_0\right)}\log{p_\theta\left(\mathbf{x}_0\right)} \\ &= -\mathbb{E}_{q\left(\mathbf{x}_0\right)}\log{\left(\int{p_\theta\left(\mathbf{x}_{0:T}\right)d\mathbf{x}_{1:T}}\right)} \\ &= -\mathbb{E}_{q\left(\mathbf{x}_0\right)}\log{\left(\int{q\left(\mathbf{x}_{1:T}\middle|\mathbf{x}_0\right)\frac{p_\theta\left(\mathbf{x}_{0:T}\right)}{q\left(\mathbf{x}_{1:T}\middle|\mathbf{x}_0\right)}d\mathbf{x}_{1:T}}\right)} \\ &= -\mathbb{E}_{q\left(\mathbf{x}_0\right)}\log{\left(\mathbb{E}_{q\left(\mathbf{x}_{1:T}\middle|\mathbf{x}_0\right)}\frac{p_\theta\left(\mathbf{x}_{0:T}\right)}{q\left(\mathbf{x}_{1:T}\middle|\mathbf{x}_0\right)}\right)} \end{align}

对于凸函数,我们可以运用詹森不等式(Jensen’s inequality),f(E[X])E[f(X)]f(\mathbb{E}[X])\leq\mathbb{E}[f(X)],这种不等式本质上是指一个期望的函数小于或等于该函数的期望。这是变分推理方法的关键组成部分,确保近似值有界且表现良好。由于 log-\log 是凸函数,应用詹森不等式得:

H(q(x0),pθ(x0))Eq(x0:T)logpθ(x0:T)q(x1:T|x0)Negative ELBO 是一个上界\begin{align} H\left(q\left(x_0\right),p_\theta\left(x_0\right)\right) &\le -\mathbb{E}_{q\left(\mathbf{x}_{0:T}\right)}\log{\frac{p_\theta\left(\mathbf{x}_{0:T}\right)}{q\left(\mathbf{x}_{1:T}\middle|\mathbf{x}_0\right)}} \quad \color{blue}{\text{Negative ELBO 是一个上界}} \end{align}
LNELBO=Eq(x0:T)logq(x1:T|x0)pθ(x0:T)L_{\mathrm{NELBO}}=\mathbb{E}_{q(\mathbf{x}_{0:T})}\log{\frac{q\left(\mathbf{x}_{1:T}\middle|\mathbf{x}_0\right)}{p_\theta\left(\mathbf{x}_{0:T}\right)}}
q(x0:T)=q(x1:T|x0)q(x0)q\left(\mathbf{x}_{0:T}\right)=q\left(\mathbf{x}_{1:T}\middle|\mathbf{x}_0\right)q\left(\mathbf{x}_0\right)

展开 LNELBOL_{\mathrm{NELBO}},利用前向过程和逆向过程的马尔可夫性质:

LNELBO=Eq(x0:T)[logq(x1:Tx0)pθ(x0:T)]=Eq[logt=1Tq(xtxt1)pθ(xT)t=1Tpθ(xt1xt)]\begin{aligned} L_{\mathrm{NELBO}} &= \mathbb{E}_{q\left(\mathbf{x}_{0:T}\right)}\left[\log \frac{q\left(\mathbf{x}_{1:T} \mid \mathbf{x}_0\right)}{p_\theta\left(\mathbf{x}_{0:T}\right)}\right] = \mathbb{E}_q\left[\log \frac{\prod_{t=1}^T q\left(\mathbf{x}_t \mid \mathbf{x}_{t-1}\right)}{p_\theta\left(\mathbf{x}_T\right) \prod_{t=1}^T p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right)}\right] \end{aligned}

对数乘法变加法

=Eq[logpθ(xT)+t=1Tlogq(xtxt1)pθ(xt1xt)]\begin{aligned} &= \mathbb{E}_q\left[-\log p_\theta\left(\mathbf{x}_T\right)+\sum_{t=1}^T \log \frac{q\left(\mathbf{x}_t \mid \mathbf{x}_{t-1}\right)}{p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right)}\right] \end{aligned}

t=1t=1 项单独写出

=Eq[logpθ(xT)+t=2Tlogq(xtxt1)pθ(xt1xt)+logq(x1x0)pθ(x0x1)]\begin{aligned} &= \mathbb{E}_q\left[-\log p_\theta\left(\mathbf{x}_T\right)+\sum_{t=2}^T \log \frac{q\left(\mathbf{x}_t \mid \mathbf{x}_{t-1}\right)}{p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right)}+\log \frac{q\left(\mathbf{x}_1 \mid \mathbf{x}_0\right)}{p_\theta\left(\mathbf{x}_0 \mid \mathbf{x}_1\right)}\right] \end{aligned}

根据贝叶斯公式 q(xt|xt1)=q(xt1xt)q(xt)q(xt1)q\left(\mathbf{x}_t\middle|\mathbf{x}_{t-1}\right)=\frac{q\left(\mathbf{x}_{t-1}|\mathbf{x}_t\right)q\left(\mathbf{x}_t\right)}{q\left(\mathbf{x}_{t-1}\right)}

=Eq[logpθ(xT)+t=2Tlog(q(xt1xt)pθ(xt1xt)q(xt)q(xt1))+logq(x1x0)pθ(x0x1)]\begin{aligned} &= \mathbb{E}_q\left[-\log p_\theta\left(\mathbf{x}_T\right)+\sum_{t=2}^T \log \left(\frac{q\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right)}{p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right)} \cdot \frac{q\left(\mathbf{x}_t \right)}{q\left(\mathbf{x}_{t-1} \right)}\right)+\log \frac{q\left(\mathbf{x}_1 \mid \mathbf{x}_0\right)}{p_\theta\left(\mathbf{x}_0 \mid \mathbf{x}_1\right)}\right] \end{aligned}

对每一项概率添加 x0\mathbf{x}_0 条件依赖,降低方差

=Eq[logpθ(xT)+t=2Tlog(q(xt1xt,x0)pθ(xt1xt)q(xtx0)q(xt1x0))+logq(x1x0)pθ(x0x1)]\begin{aligned} &= \mathbb{E}_q\left[-\log p_\theta\left(\mathbf{x}_T\right)+\sum_{t=2}^T \log \left(\frac{q\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t, \mathbf{x}_0\right)}{p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right)} \cdot \frac{q\left(\mathbf{x}_t \mid \mathbf{x}_0\right)}{q\left(\mathbf{x}_{t-1} \mid \mathbf{x}_0\right)}\right)+\log \frac{q\left(\mathbf{x}_1 \mid \mathbf{x}_0\right)}{p_\theta\left(\mathbf{x}_0 \mid \mathbf{x}_1\right)}\right] \end{aligned}

对数乘法再次变加法:

=Eq[logpθ(xT)+t=2Tlogq(xt1xt,x0)pθ(xt1xt)+t=2Tlogq(xtx0)q(xt1x0)+logq(x1x0)pθ(x0x1)]\begin{aligned} &= \mathbb{E}_q\left[-\log p_\theta\left(\mathbf{x}_T\right)+\sum_{t=2}^T \log \frac{q\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t, \mathbf{x}_0\right)}{p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right)}+\sum_{t=2}^T \log \frac{q\left(\mathbf{x}_t \mid \mathbf{x}_0\right)}{q\left(\mathbf{x}_{t-1} \mid \mathbf{x}_0\right)}+\log \frac{q\left(\mathbf{x}_1 \mid \mathbf{x}_0\right)}{p_\theta\left(\mathbf{x}_0 \mid \mathbf{x}_1\right)}\right] \end{aligned}

分子与分母展开,只有第一项 t=1t=1 和最后一项 t=Tt=T 不同,其它项可以约掉(telescoping sum):

=Eq[logpθ(xT)+t=2Tlogq(xt1xt,x0)pθ(xt1xt)+logq(xTx0)q(x1x0)+logq(x1x0)pθ(x0x1)]\begin{aligned} &= \mathbb{E}_q\left[-\log p_\theta\left(\mathbf{x}_T\right)+\sum_{t=2}^T \log \frac{q\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t, \mathbf{x}_0\right)}{p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right)}+\log \frac{q\left(\mathbf{x}_T \mid \mathbf{x}_0\right)}{q\left(\mathbf{x}_1 \mid \mathbf{x}_0\right)}+\log \frac{q\left(\mathbf{x}_1 \mid \mathbf{x}_0\right)}{p_\theta\left(\mathbf{x}_0 \mid \mathbf{x}_1\right)}\right] \end{aligned}

再做合并与消除简化

=Eq[logq(xTx0)pθ(xT)+t=2Tlogq(xt1xt,x0)pθ(xt1xt)logpθ(x0x1)]\begin{aligned} &= \mathbb{E}_q\left[\log \frac{q\left(\mathbf{x}_T \mid \mathbf{x}_0\right)}{p_\theta\left(\mathbf{x}_T\right)}+\sum_{t=2}^T \log \frac{q\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t, \mathbf{x}_0\right)}{p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right)}-\log p_\theta\left(\mathbf{x}_0 \mid \mathbf{x}_1\right)\right] \end{aligned}

根据双重期望定理 E[E[XY]]=E[X]\mathbb{E}\left[\mathbb{E}\left[X|Y\right]\right]=\mathbb{E}[X]

=Eq[Eq(xTx0)[logq(xTx0)pθ(xT)]+t=2TEq(xt1xt,x0)[logq(xt1xt,x0)pθ(xt1xt)]logpθ(x0x1)]\begin{aligned} &= \mathbb{E}_q\left[\mathbb{E}_{q\left(\mathbf{x}_T \mid \mathbf{x}_0\right)}\left[\log \frac{q\left(\mathbf{x}_T \mid \mathbf{x}_0\right)}{p_\theta\left(\mathbf{x}_T\right)}\right]+\sum_{t=2}^T \mathbb{E}_{q\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t, \mathbf{x}_0\right)}\left[\log \frac{q\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t, \mathbf{x}_0\right)}{p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right)}\right]-\log p_\theta\left(\mathbf{x}_0 \mid \mathbf{x}_1\right)\right] \end{aligned}

根据 KL 散度的定义 DKL(pq)=Ep[logpq]D_{KL}(p\|q) = \mathbb{E}_p\left[\log \frac{p}{q}\right],最终得到:

LNELBO=Eq[DKL(q(xTx0)pθ(xT))LT+t=2TDKL(q(xt1xt,x0)pθ(xt1xt))Lt1logpθ(x0x1)L0]\begin{aligned} L_{\mathrm{NELBO}} &= \mathbb{E}_q\left[\underbrace{D_{KL}\left(q\left(\mathbf{x}_T \mid \mathbf{x}_0\right) \| p_\theta\left(\mathbf{x}_T\right)\right)}_{L_T}+\sum_{t=2}^T \underbrace{D_{KL}\left(q\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t, \mathbf{x}_0\right) \| p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right)\right)}_{L_{t-1}}-\underbrace{\log p_\theta\left(\mathbf{x}_0 \mid \mathbf{x}_1\right)}_{L_0}\right] \end{aligned}

其中 LTL_T 不依赖于参数 θ\theta,可视为常数项。最大化 L0L_0 表示所有样本在 t=1t=1 时预测的高斯分布 N(x0;μθ(x1,1),σ12I)\mathcal{N}\left(\mathbf{x}_0;\boldsymbol{\mu}_\theta\left(\mathbf{x}_1,1\right),\sigma_1^2\mathbf{I}\right) 围绕 x0ix_0^i 特定区间 [σ(x0i),σ+(x0i)][\sigma_-\left(x_0^i\right),\sigma_+\left(x_0^i\right)] 累积分布质量总和最大,也就是优化高斯分布中心部分(均值 μθ(x1,1)\boldsymbol{\mu}_\theta\left(\mathbf{x}_1,1\right))与 x0ix_0^i 对齐。

L0=logpθ(x0|x1)=iDlog(σ(x0i)σ+(x0i)N(x;μθ(x1,1),σ12I)dx)L_0=\log{p_\theta}\left(\mathbf{x}_0\middle|\mathbf{x}_1\right)=\sum_{i}^{D}\log{\left(\int_{\sigma_-\left(x_0^i\right)}^{\sigma_+\left(x_0^i\right)}\mathcal{N}\left(x;\boldsymbol{\mu}_\theta\left(\mathbf{x}_1,1\right),\sigma_1^2\mathbf{I}\right)dx\right)}
σ+(x)={,if x=1x+1255,if x<1σ(x)={,if x=1x1255,if x>1\sigma_{+}(x)=\begin{cases} \infty, & \text{if } x=1 \\ x+\frac{1}{255}, & \text{if } x<1 \end{cases} \quad \sigma_{-}(x)= \begin{cases}-\infty, & \text{if } x=-1 \\ x-\frac{1}{255}, & \text{if } x>-1\end{cases}

Lt1=DKL(q(xt1|xt,x0)pθ(xt1|xt))L_{t-1}=D_{\mathrm{KL}}\left(q\left(\mathbf{x}_{t-1}\middle|\mathbf{x}_t,\mathbf{x}_0\right)\parallel p_\theta\left(\mathbf{x}_{t-1}\middle|\mathbf{x}_t\right)\right) 表示真实后验分布与模型预测分布之间的 KL 散度。我们的目标是让模型学习的逆向过程尽可能逼近真实的后验分布。

真实后验分布(已知 x0\mathbf{x}_0xt\mathbf{x}_txt1\mathbf{x}_{t-1} 的条件分布)为:

q(xt1|xt,x0)=N(xt1;μ~t,β~tI)=N(xt1;1αt(xt1αt1αˉtϵt),1αˉt11αˉtβtI)q\left(\mathbf{x}_{t-1}\middle|\mathbf{x}_t,\mathbf{x}_0\right)=\mathcal{N}\left(\mathbf{x}_{t-1};\tilde{\boldsymbol{\mu}}_t,\tilde{\beta}_t\mathbf{I}\right)=\mathcal{N}\left(\mathbf{x}_{t-1};\frac{1}{\sqrt{\alpha_t}}\left(\mathbf{x}_t-\frac{1-\alpha_t}{\sqrt{1-\bar{\alpha}_t}}\boldsymbol{\epsilon}_t\right),\frac{1-\bar{\alpha}_{t-1}}{1-\bar{\alpha}_t}\cdot\beta_t\mathbf{I}\right)

模型预测的逆向分布采样公式(需要学习的分布)为:

pθ(xt1|xt)=N(xt1;μθ(xt,t),Σθ(xt,t))=N(xt1;1αt(xt1αt1αˉtϵθ(xt,t)),βtI)\color{blue}{ p_\theta\left(\mathbf{x}_{t-1}\middle|\mathbf{x}_t\right) =\mathcal{N}\left(\mathbf{x}_{t-1};\,\boldsymbol{\mu}_\theta\left(\mathbf{x}_t,t\right),\,\boldsymbol{\Sigma}_\theta\left(\mathbf{x}_t,t\right)\right) =\mathcal{N}\left(\mathbf{x}_{t-1};\,\frac{1}{\sqrt{\alpha_t}}\left(\mathbf{x}_t-\frac{1-\alpha_t}{\sqrt{1-\bar{\alpha}_t}}\,\boldsymbol{\epsilon}_\theta(\mathbf{x}_t,t)\right),\,\beta_t\mathbf{I}\right) }

由于两者都是高斯分布,我们可以利用高斯分布 KL 散度的解析形式来计算:

KL(N(μ1,Σ12)N(μ2,Σ22))=12(logΣ22logΣ12+Σ12+(μ1μ2)2Σ221)\mathrm{KL}\left(\mathcal{N}\left(\boldsymbol{\mu}_1,\boldsymbol{\Sigma}_1^2\right)\parallel\mathcal{N}\left(\boldsymbol{\mu}_2,\boldsymbol{\Sigma}_2^2\right)\right)=\frac{1}{2}\left(\log\boldsymbol{\Sigma}_2^2-\log\boldsymbol{\Sigma}_1^2+\frac{\boldsymbol{\Sigma}_1^2+\left(\boldsymbol{\mu}_1-\boldsymbol{\mu}_2\right)^2}{\boldsymbol{\Sigma}_2^2}-1\right)

简化的损失函数:预测噪声

因为 βt\beta_t 是提前定制的,所以我在计算损失中我们不考虑方差。在损失函数最小化过程中我们只关心均值,不仅如此,我们实际上是预测噪声 ϵ\boldsymbol{\epsilon}:

Lt1=Ex0,ϵ[12Σθ(xt,t)22μ~t(xt,x0)μθ(xt,t)2]=Ex0,ϵ[12Σθ221αt(xt1αt1αˉtϵt)1αt(xt1αt1αˉtϵθ(xt,t))2]=Ex0,ϵ[(1αt)22αt(1αˉt)Σθ22ϵtϵθ(xt,t)2]=Ex0,ϵ[(1αt)22αt(1αˉt)Σθ22ϵtϵθ(αˉtx0+1αˉtϵt,t)2]\begin{aligned} L_{t-1} &= \mathbb{E}_{\mathbf{x}_0,\boldsymbol{\epsilon}}\left[\frac{1}{2\|\boldsymbol{\Sigma}_\theta(\mathbf{x}_t,t)\|_2^2}\|\tilde{\boldsymbol{\mu}}_t(\mathbf{x}_t,\mathbf{x}_0)-\boldsymbol{\mu}_\theta(\mathbf{x}_t,t)\|^2\right] \\ &= \mathbb{E}_{\mathbf{x}_0,\boldsymbol{\epsilon}}\left[\frac{1}{2\|\boldsymbol{\Sigma}_\theta\|_2^2}\left\|\frac{1}{\sqrt{\alpha_t}}\left(\mathbf{x}_t-\frac{1-\alpha_t}{\sqrt{1-\bar{\alpha}_t}}\boldsymbol{\epsilon}_t\right)-\frac{1}{\sqrt{\alpha_t}}\left(\mathbf{x}_t-\frac{1-\alpha_t}{\sqrt{1-\bar{\alpha}_t}}\boldsymbol{\epsilon}_\theta(\mathbf{x}_t,t)\right)\right\|^2\right] \\ &= \mathbb{E}_{\mathbf{x}_0,\boldsymbol{\epsilon}}\left[\frac{(1-\alpha_t)^2}{2\alpha_t(1-\bar{\alpha}_t)\|\boldsymbol{\Sigma}_\theta\|_2^2}\|\boldsymbol{\epsilon}_t-\boldsymbol{\epsilon}_\theta(\mathbf{x}_t,t)\|^2\right] \\ &= \mathbb{E}_{\mathbf{x}_0,\boldsymbol{\epsilon}}\left[\frac{(1-\alpha_t)^2}{2\alpha_t(1-\bar{\alpha}_t)\|\boldsymbol{\Sigma}_\theta\|_2^2}\|\boldsymbol{\epsilon}_t-\boldsymbol{\epsilon}_\theta(\sqrt{\bar{\alpha}_t}\mathbf{x}_0+\sqrt{1-\bar{\alpha}_t}\boldsymbol{\epsilon}_t,t)\|^2\right] \end{aligned}

最终发现忽略权重结果更好,这不再是对数似然的变分下界。

Lt1simple=Et[1,T],x0,ϵt[ϵtϵθ(xt,t)2]=Et[1,T],x0,ϵt[ϵtϵθ(αˉtx0+1αˉtϵt,t)2]+C\begin{aligned} L_{t-1}^{\mathrm{simple}} &= \mathbb{E}_{t\sim[1,T],\mathbf{x}_0,\boldsymbol{\epsilon}_t}\left[\|\boldsymbol{\epsilon}_t-\boldsymbol{\epsilon}_\theta(\mathbf{x}_t,t)\|^2\right] \\ &= \mathbb{E}_{t\sim[1,T],\mathbf{x}_0,\boldsymbol{\epsilon}_t}\left[\|\boldsymbol{\epsilon}_t-\boldsymbol{\epsilon}_\theta(\sqrt{\bar{\alpha}_t}\mathbf{x}_0+\sqrt{1-\bar{\alpha}_t}\boldsymbol{\epsilon}_t,t)\|^2\right]+C \end{aligned}

DDPM 训练算法

Algorithm 1: Trainingrepeatx0q(x0)从数据分布中采样tUniform({1,,T})随机选择时间步ϵN(0,I)采样高斯噪声梯度下降更新: θϵϵθ(αˉtx0+1αˉtϵ,t)2until converged\begin{array}{l} \textbf{Algorithm 1: Training} \\ \hline \textbf{repeat} \\ \quad \mathbf{x}_0 \sim q(\mathbf{x}_0) \quad \text{从数据分布中采样} \\ \quad t \sim \text{Uniform}(\{1, \ldots, T\}) \quad \text{随机选择时间步} \\ \quad \boldsymbol{\epsilon} \sim \mathcal{N}(\mathbf{0}, \mathbf{I}) \quad \text{采样高斯噪声} \\ \quad \text{梯度下降更新: } \nabla_\theta \left\|\boldsymbol{\epsilon} - \boldsymbol{\epsilon}_\theta\left(\sqrt{\bar{\alpha}_t}\mathbf{x}_0 + \sqrt{1-\bar{\alpha}_t}\boldsymbol{\epsilon}, t\right)\right\|^2 \\ \textbf{until converged} \end{array}

DDPM 采样算法(根据逆向分布采样公式)

Algorithm 2: SamplingxTN(0,I)从纯噪声开始for t=T,,1 dozN(0,I) if t>1, else z=0xt1=1αt(xt1αt1αˉtϵθ(xt,t))+σtzend forreturn x0\begin{array}{l} \textbf{Algorithm 2: Sampling} \\ \hline \mathbf{x}_T \sim \mathcal{N}(\mathbf{0}, \mathbf{I}) \quad \text{从纯噪声开始} \\ \textbf{for } t = T, \ldots, 1 \textbf{ do} \\ \quad \mathbf{z} \sim \mathcal{N}(\mathbf{0}, \mathbf{I}) \text{ if } t > 1 \text{, else } \mathbf{z} = \mathbf{0} \\ \quad \mathbf{x}_{t-1} = \frac{1}{\sqrt{\alpha_t}}\left(\mathbf{x}_t - \frac{1-\alpha_t}{\sqrt{1-\bar{\alpha}_t}}\boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t)\right) + \sigma_t\mathbf{z} \\ \textbf{end for} \\ \textbf{return } \mathbf{x}_0 \end{array}

其中 σt=1αˉt11αˉtβt\sigma_t = \sqrt{\frac{1-\bar{\alpha}_{t-1}}{1-\bar{\alpha}_t} \cdot \beta_t} 是逆向过程的噪声标准差。

训练算法的核心思想是:对于每个训练样本,随机选择一个时间步 tt,然后根据前向过程公式生成加噪样本 xt\mathbf{x}_t,并训练神经网络预测添加的噪声 ϵ\boldsymbol{\epsilon}

采样算法则从纯噪声 xT\mathbf{x}_T 开始,通过迭代地应用学习到的去噪函数,逐步恢复出原始样本 x0\mathbf{x}_0

图像生成的扩散模型

正向过程:将图像分布转换为纯噪声

正向过程:将图像分布转换为纯噪声

逆过程:从图像分布中采样,从纯噪声开始

逆过程:从图像分布中采样,从纯噪声开始

扩散加速:去噪扩散隐式模型(DDIM)

DDPM马尔可夫链模型

DDPM马尔可夫链模型

DDIM非马尔可夫链模型

DDIM非马尔可夫链模型

当采用基于逆向扩散过程的马尔可夫链DDPM生成样本时,由于迭代次数可达几千步,生成速度相对较慢。为了加速采样,去噪扩散隐式模型(Denoising Diffusion Implicit Models, DDIM)提出了一类更高效的迭代隐式概率模型。

马尔可夫 vs 非马尔可夫:为什么 DDIM 可以跳步?

DDPM(马尔可夫过程)的限制:

在 DDPM 中,正向扩散过程定义为马尔可夫链,即 xt\mathbf{x}_t 仅依赖于 xt1\mathbf{x}_{t-1}

q(xtxt1,x0)=q(xtxt1)q(\mathbf{x}_t | \mathbf{x}_{t-1}, \mathbf{x}_0) = q(\mathbf{x}_t | \mathbf{x}_{t-1})

这意味着:给定 xt1\mathbf{x}_{t-1}x0\mathbf{x}_0 不提供关于 xt\mathbf{x}_t 的额外信息——这就是马尔可夫性质(“无记忆性”)。因此,逆向生成过程必须严格逐步进行:xTxT1x1x0\mathbf{x}_T \to \mathbf{x}_{T-1} \to \cdots \to \mathbf{x}_1 \to \mathbf{x}_0,无法跳过任何中间步骤。

DDIM(非马尔可夫过程)的突破:

DDIM 重新定义了正向过程,使 xt\mathbf{x}_t 同时依赖于 xt1\mathbf{x}_{t-1}x0\mathbf{x}_0

q(xtxt1,x0)q(xtxt1)q(\mathbf{x}_t | \mathbf{x}_{t-1}, \mathbf{x}_0) \neq q(\mathbf{x}_t | \mathbf{x}_{t-1})

关键在于:DDIM 构造的联合分布保持与 DDPM 相同的边际分布 q(xtx0)q(\mathbf{x}_t|\mathbf{x}_0),但转移过程 q(xtxt1,x0)q(\mathbf{x}_t|\mathbf{x}_{t-1}, \mathbf{x}_0) 是确定性的(或半确定性的)。由于过程"记住"了起点 x0\mathbf{x}_0,打破了马尔可夫的"无记忆性"。

为什么非马尔可夫允许跳步?

由于 DDPM 的训练目标仅依赖于边际分布 q(xtx0)q(\mathbf{x}_t|\mathbf{x}_0)(描述在时刻 tt 添加了多少噪声),而不是整个轨迹的联合分布 q(x1:Tx0)q(\mathbf{x}_{1:T}|\mathbf{x}_0),DDIM 可以:

  1. 复用相同的预训练模型:神经网络 ϵθ(xt,t)\boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t) 只需从 xt\mathbf{x}_t 预测噪声,不关心具体的采样路径。

  2. 在任意子序列上采样:逆向过程可以定义在时间步的子集 τ1,τ2,,τS\tau_1, \tau_2, \ldots, \tau_S(其中 STS \ll T)上。

  3. 直接跳跃:DDIM 的更新公式显式利用预测的 x^0\hat{\mathbf{x}}_0,本质上是说:“我知道当前位置 xt\mathbf{x}_t,我有对目标 x^0\hat{\mathbf{x}}_0 的估计,我可以沿着这条线跳到任意中间点 xs\mathbf{x}_ss<ts < t)。”

DDIM 推导

接下来将可控噪声(标准偏差为 σt\sigma_t)引入到逆向生成过程(从 xt\mathbf{x}_t 采样 xt1\mathbf{x}_{t-1})。构建一个可训练的生成过程 pθ(x0:T)p_\theta(\mathbf{x}_{0:T}),其中每个 pθ(t)(xt1xt)p_\theta^{(t)}(\mathbf{x}_{t-1}|\mathbf{x}_t) 通过计算条件概率 qσ(xt1xt,x0)q_\sigma(\mathbf{x}_{t-1}|\mathbf{x}_t,\mathbf{x}_0) 获得。在推断时,给定一个噪声样本 xt\mathbf{x}_t,运用神经网络对原样本进行预测 x^0=fθ(t)(xt)\hat{\mathbf{x}}_0=f_\theta^{(t)}(\mathbf{x}_t),然后再通过逆向条件分布 qσ(xt1xt,x^0)q_\sigma(\mathbf{x}_{t-1}|\mathbf{x}_t,\hat{\mathbf{x}}_0) 获得样本 xt1\mathbf{x}_{t-1}

由于重参数化,我们有:

xt=αˉtx0+1αˉtϵx0=xt1αˉtϵαˉt\mathbf{x}_t = \sqrt{\bar{\alpha}_t}\mathbf{x}_0 + \sqrt{1-\bar{\alpha}_t}\boldsymbol{\epsilon} \quad \Rightarrow \quad \mathbf{x}_0 = \frac{\mathbf{x}_t - \sqrt{1-\bar{\alpha}_t}\boldsymbol{\epsilon}}{\sqrt{\bar{\alpha}_t}}

同理,对于 xt1\mathbf{x}_{t-1}

xt1=αˉt1x0+1αˉt1ϵt1\mathbf{x}_{t-1} = \sqrt{\bar{\alpha}_{t-1}}\mathbf{x}_0 + \sqrt{1-\bar{\alpha}_{t-1}}\boldsymbol{\epsilon}_{t-1}

其中,ϵt1\boldsymbol{\epsilon}_{t-1} 可以由 ϵt\boldsymbol{\epsilon}_t 和新噪声 ϵ\boldsymbol{\epsilon} 组合得到:

ϵt1=1αˉt1σt21αˉt1ϵt+σt1αˉt1ϵ\boldsymbol{\epsilon}_{t-1} = \frac{\sqrt{1-\bar{\alpha}_{t-1}-\sigma_t^2}}{\sqrt{1-\bar{\alpha}_{t-1}}}\boldsymbol{\epsilon}_t + \frac{\sigma_t}{\sqrt{1-\bar{\alpha}_{t-1}}}\boldsymbol{\epsilon}

x0\mathbf{x}_0ϵt1\boldsymbol{\epsilon}_{t-1} 代入,得到:

xt1=αˉt1x0+1αˉt1ϵt1=αˉt1x0+1αˉt1σt2ϵt+σtϵ=αˉt1xt1αˉtϵtαˉt+1αˉt1σt2ϵt+σtϵ\begin{aligned} \mathbf{x}_{t-1} &= \sqrt{\bar{\alpha}_{t-1}}\mathbf{x}_0 + \sqrt{1-\bar{\alpha}_{t-1}}\boldsymbol{\epsilon}_{t-1} \\ &= \sqrt{\bar{\alpha}_{t-1}}\mathbf{x}_0 + \sqrt{1-\bar{\alpha}_{t-1}-\sigma_t^2}\boldsymbol{\epsilon}_t + \sigma_t\boldsymbol{\epsilon} \\ &= \sqrt{\bar{\alpha}_{t-1}} \cdot \frac{\mathbf{x}_t - \sqrt{1-\bar{\alpha}_t}\boldsymbol{\epsilon}_t}{\sqrt{\bar{\alpha}_t}} + \sqrt{1-\bar{\alpha}_{t-1}-\sigma_t^2}\boldsymbol{\epsilon}_t + \sigma_t\boldsymbol{\epsilon} \end{aligned}

在实际推断中,输入 xt\mathbf{x}_t,运用神经网络 ϵθ(t)(xt)\boldsymbol{\epsilon}_\theta^{(t)}(\mathbf{x}_t) 预测噪声 ϵt\boldsymbol{\epsilon}_t,从而估计原始样本:

x^0=fθ(t)(xt)=xt1αˉtϵθ(t)(xt)αˉt\hat{\mathbf{x}}_0 = f_\theta^{(t)}(\mathbf{x}_t) = \frac{\mathbf{x}_t - \sqrt{1-\bar{\alpha}_t}\boldsymbol{\epsilon}_\theta^{(t)}(\mathbf{x}_t)}{\sqrt{\bar{\alpha}_t}}

将预测的噪声代入 DDIM 更新公式,我们有:

xt1=αˉt1xt1αˉtϵθ(t)(xt)αˉt+1αˉt1σt2ϵθ(t)(xt)+σtϵ=αˉt1x^0+1αˉt1σt2ϵθ(t)(xt)+σtϵ\begin{aligned} \mathbf{x}_{t-1} &= \sqrt{\bar{\alpha}_{t-1}} \cdot \frac{\mathbf{x}_t - \sqrt{1-\bar{\alpha}_t}\boldsymbol{\epsilon}_\theta^{(t)}(\mathbf{x}_t)}{\sqrt{\bar{\alpha}_t}} + \sqrt{1-\bar{\alpha}_{t-1}-\sigma_t^2}\boldsymbol{\epsilon}_\theta^{(t)}(\mathbf{x}_t) + \sigma_t\boldsymbol{\epsilon} \\ &= \sqrt{\bar{\alpha}_{t-1}}\hat{\mathbf{x}}_0 + \sqrt{1-\bar{\alpha}_{t-1}-\sigma_t^2}\boldsymbol{\epsilon}_\theta^{(t)}(\mathbf{x}_t) + \sigma_t\boldsymbol{\epsilon} \end{aligned}

因此,逆向条件分布为:

qσ(xt1xt,x^0)=N(xt1;αˉt1x^0+1αˉt1σt2ϵθ(t)(xt),σt2I)q_\sigma(\mathbf{x}_{t-1}|\mathbf{x}_t,\hat{\mathbf{x}}_0) = \mathcal{N}\left(\mathbf{x}_{t-1}; \sqrt{\bar{\alpha}_{t-1}}\hat{\mathbf{x}}_0 + \sqrt{1-\bar{\alpha}_{t-1}-\sigma_t^2}\boldsymbol{\epsilon}_\theta^{(t)}(\mathbf{x}_t), \sigma_t^2\mathbf{I}\right)

生成过程被认为是逆过程的近似;由于正向过程有 TT 步骤,生成过程也被迫采样 TT 步骤。然而,作为去噪目标只要求 qσ(xtx0)q_\sigma(\mathbf{x}_t|\mathbf{x}_0) 固定,不依赖于具体的正向过程,我们也可以考虑长度小于 TT 的正向过程,从而加速生成过程,而无需训练不同的模型。在生成过程中,我们不必遍历整个链的每个节点 t=1,,Tt=1,\ldots,T,而只需遍历部分节点。下面将加速路径中的任意两个节点表示为 s<ts < t。 DDIM 更新步骤为:

σt(η)=η(1αˉtαˉs)1αˉs1αˉt\sigma_t(\eta) = \eta \cdot \sqrt{\left(1-\frac{\bar{\alpha}_t}{\bar{\alpha}_s}\right)\frac{1-\bar{\alpha}_s}{1-\bar{\alpha}_t}}
qσ,s<t(xsxt,x^0)=N(xs;αˉsx^0+1αˉsσt2ϵθ(t)(xt),σt2I)q_{\sigma, s < t}(\mathbf{x}_s | \mathbf{x}_t, \hat{\mathbf{x}}_0) = \mathcal{N}\left(\mathbf{x}_s; \sqrt{\bar{\alpha}_s} \hat{\mathbf{x}}_0 + \sqrt{1-\bar{\alpha}_s - \sigma_t^2} \, \boldsymbol{\epsilon}_\theta^{(t)}(\mathbf{x}_t), \sigma_t^2 \mathbf{I} \right)

其中 η[0,1]\eta \in [0,1] 为超参数,当 η=1\eta=1 时,对应原本 DDPM;当 η=0\eta=0 时,对应 σt=0\sigma_t=0,即 DDIM 固定采样。对于所有 t1t \neq 1,给定 xt1\mathbf{x}_{t-1}x0\mathbf{x}_0 时,正向过程变成固定的;在生成过程中,添加的随机噪声也将为零。

与 DDPM 相比,DDIM 能够:

  • 使用更少的步骤生成更高质量的样本。

  • 具有“一致性”属性,因为生成过程是确定性的,这意味着以同一隐变量为条件的多个样本应该具有相似的高级特征。

  • 由于一致性,DDIM 可以在隐变量中进行语义上有意义的插值。

下图为不同设置的扩散模型在 CIFAR10 和 CelebA 数据集上的 FID 指标(Fréchet Inception Distance,数值越小越好):DDIM(η=0\eta=0)、DDPM(σ^\hat{\sigma})、迭代次数 SS

IDDPM改进:可学习的方差调度变量

去噪扩散概率模型(DDPM)将正向过程中的方差 βt\beta_t 设置为一个线性增长的常数序列,从 β1=104\beta_1=10^{-4}βT=0.02\beta_T=0.02。相较于归一化到 [1,1][-1, 1] 的图像像素值,这样的 βt\beta_t 相对较小。虽然基于线性方差调度的扩散模型在实验中可以生成高质量样本,但其对数似然(negative log-likelihood, NLL)仍不如其他生成模型(如VAE)具有竞争力。

Nichol & Dhariwal (2021) 提出了一些改进技术,以帮助扩散模型获得更低的负对数似然值。其中一个重要改进就是采用基于余弦函数的方差调度。只要调度函数 f(t)f(t) 在训练过程的中间部分呈现近似线性下降,并且在 t=1t=1t=Tt=T 附近变化较慢即可,不拘泥于特定的函数形式。典型的余弦方差调度如下:

βt=clip(1αˉtαˉt1,0,0.999)\beta_t = \mathrm{clip}\left( 1 - \frac{\bar{\alpha}_t}{\bar{\alpha}_{t-1}},\, 0,\, 0.999 \right)
αˉt=f(t)f(0)\bar{\alpha}_t = \frac{f(t)}{f(0)}
其中f(t)=cos2(tT+s1+sπ2)\text{其中} \quad f(t) = \cos^2\left( \frac{\frac{t}{T} + s}{1 + s} \cdot \frac{\pi}{2} \right)

其中偏置 ss 用于防止方差调度在 t=0t=0 附近变得过小。

  • 线性方差调度可以非常快地将初始样本转换为噪声,这样会使模型更难学习逆向过程。

  • 在端点附近引入相对缓慢的变化可能效果更好,例如余弦函数

    • 结果表明确实有更好的效果,但余弦的选择完全是任意的

线性(上)与余弦(下)

线性(上)与余弦(下)

学习协方差矩阵

去噪扩散概率模型(DDPM)的研究发现,使用固定的协方差矩阵(例如 Σθ(xt,t)=βtI\boldsymbol{\Sigma}_\theta(\mathbf{x}_t,t)=\beta_t\mathbf{I} 或者 Σθ(xt,t)=β~tI\boldsymbol{\Sigma}_\theta(\mathbf{x}_t,t)=\tilde{\beta}_t\mathbf{I})也能取得很好的效果:

  • βtI\beta_t\mathbf{I} 对应于假设 x0N(0,I)x_0 \sim \mathcal{N}(0, \mathbf{I}) 时的上限。

  • β~tI\tilde{\beta}_t\mathbf{I} 对应于给定 x0x_0 时的真实后验方差(下限)。

虽然固定方差在生成质量上表现不错,但实验表明学习协方差矩阵可以进一步提高对数似然值(Log-Likelihood)。Nichol & Dhariwal 提出了通过模型输出一个插值系数 v\mathbf{v} 来学习协方差 Σθ(xt,t)\boldsymbol{\Sigma}_\theta(\mathbf{x}_t,t),该协方差在 βt\beta_tβ~t\tilde{\beta}_t 之间进行对数域插值:

Σθ(xt,t)=exp(vlogβt+(1v)logβ~t)\boldsymbol{\Sigma}_\theta(\mathbf{x}_t,t) = \exp\left(\mathbf{v} \odot \log \beta_t + (1-\mathbf{v}) \odot \log \tilde{\beta}_t\right)

其中 v\mathbf{v} 是神经网络输出的一个与 x\mathbf{x} 维度相同的向量,取值范围在 [0,1][0, 1] 之间。

混合损失函数优化协方差

DDPM 原有的简化损失函数 LsimpleL_{\text{simple}} 仅用于学习均值 μθ\boldsymbol{\mu}_\theta(通过预测噪声 ϵθ\boldsymbol{\epsilon}_\theta),它并不包含关于协方差 Σθ\boldsymbol{\Sigma}_\theta 的梯度信息。为了学习协方差,他们构建了一个混合损失函数:

Lhybrid=Lsimple+λLvlbL_{\text{hybrid}} = L_{\text{simple}} + \lambda L_{\text{vlb}}

其中 λ=0.001\lambda=0.001。这样,LsimpleL_{\text{simple}} 主导均值的学习,而 LvlbL_{\text{vlb}}(变分下界损失)则为协方差的学习提供梯度信号。

重要性采样与动态权重调整

由于 LvlbL_{\text{vlb}} 包含对所有时间步 tt 的求和,直接均匀采样 tt 会导致梯度估计方差较大,收敛困难。因此,作者采用了重要性采样(Importance Sampling)来优化 LvlbL_{\text{vlb}}

Lvlb=Etpt[Ltpt],where ptE[Lt2]andpt=1L_{\text{vlb}} = \mathbb{E}_{t \sim p_t}\left[\frac{L_t}{p_t}\right], \quad \text{where } p_t \propto \sqrt{\mathbb{E}\left[L_t^2\right]} \quad \text{and} \quad \sum p_t = 1

由于 E[Lt2]\mathbb{E}[L_t^2] 事先未知且在训练过程中会发生变化,因此训练时会维护每个时间步损失项 LtL_t 的历史记录(例如保留前 10 个值),并动态更新采样概率 ptp_t,从而让模型更多地关注那些损失较大的时间步(通常是较难学习的阶段)。

U-Net架构与成熟模块组合

扩散模型通常使用U-Net作为噪声预测模型 – 与已经成熟的模型组合:

  • 位置编码

  • ResNet 块

  • ConvNext 块

  • 注意力模块

  • 组标准化

  • Swish和GeLU

  • Nichol 和 Dhariwal 提出了一些有助于扩散训练的架构变化:

  1. 增加模型深度与宽度(不是两者):两者都有帮助,但增加宽度在计 算上更高效,同时提供与增加深度类似的增益

  2. 增加注意力头的数量并将其应用于多种分辨率

  3. 借用 BigGAN 残差块进行上采样和下采样

  4. 自适应组标准化 —— 希望在训练/逆向过程中更好地结合时间步长(以及隐类别)信息

分类器引导的扩散模型

条件生成对抗网络可以按照类标签为条件来合成特定类型的图像。我们可以将同样的想法应用于扩散模型。Nichol & Dhariwal (2021) 在噪声图像 xt1\mathbf{x}_{t-1} 上训练分类器 pϕ(yxt1,t1)p_\phi(y|\mathbf{x}_{t-1}, t-1),并通过改变噪声预测,使用梯度 xlogpϕ(yxt1)\nabla_{\mathbf{x}} \log p_\phi(y|\mathbf{x}_{t-1}) 引导逆向扩散采样朝条件信息 yy 方向(例如类标签)。

对于无条件逆向噪声过程 pθ(xt1xt)p_\theta(\mathbf{x}_{t-1}|\mathbf{x}_t),为了添加条件标签 yy 约束,对于每次扩散只需根据以下条件概率进行采样:

pθ,ϕ(xt1xt,y)=Zpθ(xt1xt)pϕ(yxt1)p_{\theta,\phi}(\mathbf{x}_{t-1}|\mathbf{x}_t, y) = Z \cdot p_\theta(\mathbf{x}_{t-1}|\mathbf{x}_t) \cdot p_\phi(y|\mathbf{x}_{t-1})

其中 ZZ 是一个归一化常量。

分类器引导的核心思想:

  • 采用预先训练的无条件扩散模型

  • 在采样期间,将分类器模型在噪声图像上训练的梯度注入到无条件逆过程中

  • 分类器引导牺牲图像多样性以换取模型保真度,使扩散模型的生成性能超越生成对抗网络

分类器引导的数学推导

逆向过程的条件分布为:

pθ(xt1xt)=N(xt1;μθ(xt,t),Σθ(xt,t))p_\theta(\mathbf{x}_{t-1}|\mathbf{x}_t) = \mathcal{N}(\mathbf{x}_{t-1}; \boldsymbol{\mu}_\theta(\mathbf{x}_t, t), \boldsymbol{\Sigma}_\theta(\mathbf{x}_t, t))

随着扩散迭代数递增,虽然 pθ(xt1xt)p_\theta(\mathbf{x}_{t-1}|\mathbf{x}_t) 高斯分布的曲率 Σθ1\boldsymbol{\Sigma}_\theta^{-1} 会逐渐增大,但 logpϕ(yxt1)\log p_\phi(y|\mathbf{x}_{t-1}) 的曲率会降低。因此可以在 xt1=μ\mathbf{x}_{t-1} = \boldsymbol{\mu} 附近以泰勒展开来近似:

logpϕ(yxt1)logpϕ(yxt1)xt1=μ+(xt1μ)xt1logpϕ(yxt1)xt1=μ\log p_\phi(y|\mathbf{x}_{t-1}) \approx \log p_\phi(y|\mathbf{x}_{t-1})\big|_{\mathbf{x}_{t-1}=\boldsymbol{\mu}} + (\mathbf{x}_{t-1} - \boldsymbol{\mu})^\top \nabla_{\mathbf{x}_{t-1}} \log p_\phi(y|\mathbf{x}_{t-1})\big|_{\mathbf{x}_{t-1}=\boldsymbol{\mu}}

将联合分布取对数:

log(pθ(xt1xt)pϕ(yxt1))logN(xt1;μθ,Σθ)+logpϕ(yμ)+(xt1μ)g=12(xt1μθ)Σθ1(xt1μθ)+(xt1μ)g+C\begin{aligned} &\log\left(p_\theta(\mathbf{x}_{t-1}|\mathbf{x}_t) \cdot p_\phi(y|\mathbf{x}_{t-1})\right) \\ &\approx \log \mathcal{N}(\mathbf{x}_{t-1}; \boldsymbol{\mu}_\theta, \boldsymbol{\Sigma}_\theta) + \log p_\phi(y|\boldsymbol{\mu}) + (\mathbf{x}_{t-1} - \boldsymbol{\mu})^\top \mathbf{g} \\ &= -\frac{1}{2}(\mathbf{x}_{t-1} - \boldsymbol{\mu}_\theta)^\top \boldsymbol{\Sigma}_\theta^{-1} (\mathbf{x}_{t-1} - \boldsymbol{\mu}_\theta) + (\mathbf{x}_{t-1} - \boldsymbol{\mu})^\top \mathbf{g} + C \end{aligned}

其中 g=xt1logpϕ(yxt1)xt1=μ\mathbf{g} = \nabla_{\mathbf{x}_{t-1}} \log p_\phi(y|\mathbf{x}_{t-1})\big|_{\mathbf{x}_{t-1}=\boldsymbol{\mu}}

X=xt1μθ\mathbf{X} = \mathbf{x}_{t-1} - \boldsymbol{\mu}_\thetaΣ=Σθ\boldsymbol{\Sigma} = \boldsymbol{\Sigma}_\theta,通过配方:

12XΣ1X+Xg+C=12XΣ1X+XΣ1Σg+C=12(XΣg)Σ1(XΣg)+C=12(xt1(μθ+Σg))Σ1(xt1(μθ+Σg))+C\begin{aligned} &-\frac{1}{2}\mathbf{X}^\top \boldsymbol{\Sigma}^{-1} \mathbf{X} + \mathbf{X}^\top \mathbf{g} + C \\ &= -\frac{1}{2}\mathbf{X}^\top \boldsymbol{\Sigma}^{-1} \mathbf{X} + \mathbf{X}^\top \boldsymbol{\Sigma}^{-1} \boldsymbol{\Sigma} \mathbf{g} + C \\ &= -\frac{1}{2}(\mathbf{X} - \boldsymbol{\Sigma}\mathbf{g})^\top \boldsymbol{\Sigma}^{-1} (\mathbf{X} - \boldsymbol{\Sigma}\mathbf{g}) + C' \\ &= -\frac{1}{2}(\mathbf{x}_{t-1} - (\boldsymbol{\mu}_\theta + \boldsymbol{\Sigma}\mathbf{g}))^\top \boldsymbol{\Sigma}^{-1} (\mathbf{x}_{t-1} - (\boldsymbol{\mu}_\theta + \boldsymbol{\Sigma}\mathbf{g})) + C' \end{aligned}

因此,条件分布仍然是高斯分布,均值发生了偏移:

pθ,ϕ(xt1xt,y)=N(xt1;μθ+Σθxt1logpϕ(yxt1),Σθ)p_{\theta,\phi}(\mathbf{x}_{t-1}|\mathbf{x}_t, y) = \mathcal{N}\left(\mathbf{x}_{t-1}; \boldsymbol{\mu}_\theta + \boldsymbol{\Sigma}_\theta \nabla_{\mathbf{x}_{t-1}} \log p_\phi(y|\mathbf{x}_{t-1}), \boldsymbol{\Sigma}_\theta\right)

添加梯度缩放变量 ss 来控制引导强度:

pθ,ϕ(xt1xt,y)=N(xt1;μθ+sΣθxt1logpϕ(yxt1),Σθ)p_{\theta,\phi}(\mathbf{x}_{t-1}|\mathbf{x}_t, y) = \mathcal{N}\left(\mathbf{x}_{t-1}; \boldsymbol{\mu}_\theta + s \boldsymbol{\Sigma}_\theta \nabla_{\mathbf{x}_{t-1}} \log p_\phi(y|\mathbf{x}_{t-1}), \boldsymbol{\Sigma}_\theta\right)

Algorithm 1: Classifier Guided Diffusion Sampling

Input:  given a diffusion model (μθ(xt),Σθ(xt)), classifier pϕ(yxt), and gradient scale sxTN(0,I)for t=T,,1 doμ,Σμθ(xt,t),Σθ(xt,t)xt1N(μ+sΣxtlogpϕ(yxt),Σ)end forreturn x0\begin{array}{l} \hline \textbf{Input: } \text{ given a diffusion model }\left(\mu_\theta\left(x_t\right), \Sigma_\theta\left(x_t\right)\right) \text {, classifier } p_\phi\left(y \mid x_t\right) \text {, and gradient scale } s \text {. }\\ \hline \mathbf{x}_T \sim \mathcal{N}(\mathbf{0}, \mathbf{I}) \\ \textbf{for } t = T, \ldots, 1 \textbf{ do} \\ \quad \boldsymbol{\mu}, \boldsymbol{\Sigma} \leftarrow \boldsymbol{\mu}_\theta(\mathbf{x}_t, t), \boldsymbol{\Sigma}_\theta(\mathbf{x}_t, t) \\ \quad \mathbf{x}_{t-1} \sim \mathcal{N}\left(\boldsymbol{\mu} + s \boldsymbol{\Sigma} \nabla_{\mathbf{x}_t} \log p_\phi(y|\mathbf{x}_t), \boldsymbol{\Sigma}\right) \\ \textbf{end for} \\ \textbf{return } \mathbf{x}_0 \\ \hline \end{array}

基于 Score Matching 的分类器引导

前面条件采样的推导仅适用于随机扩散采样过程,但不适用于确定性采样方法(如 DDIM)。下面介绍一种基于样本梯度匹配(Score Matching)的采样方法。

Score 是对数概率密度关于样本的梯度 sθ(xt,t)xtlogpθ(xt)\mathbf{s}_\theta(\mathbf{x}_t, t) \approx \nabla_{\mathbf{x}_t} \log p_\theta(\mathbf{x}_t),本质上它测量概率密度在样本空间中不同方向上如何变化。

对于样本 xt\mathbf{x}_t(不包括标签),Score 可定义为:

xtlogpθ(xt)ϵθ(xt,t)1αˉt\nabla_{\mathbf{x}_t} \log p_\theta(\mathbf{x}_t) \approx -\frac{\boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t)}{\sqrt{1-\bar{\alpha}_t}}

详细推导过程:

Step 1: 条件分布的 Score

根据前向扩散过程的重参数化,我们有:

q(xtx0)=N(xt;αˉtx0,(1αˉt)I)q(\mathbf{x}_t|\mathbf{x}_0) = \mathcal{N}(\mathbf{x}_t; \sqrt{\bar{\alpha}_t}\mathbf{x}_0, (1-\bar{\alpha}_t)\mathbf{I})

这意味着 xt\mathbf{x}_t 可以写成:

xt=αˉtx0+1αˉtϵ,where ϵN(0,I)\mathbf{x}_t = \sqrt{\bar{\alpha}_t}\mathbf{x}_0 + \sqrt{1-\bar{\alpha}_t}\boldsymbol{\epsilon}, \quad \text{where } \boldsymbol{\epsilon} \sim \mathcal{N}(\mathbf{0}, \mathbf{I})

Step 2: 高斯分布的 Score 公式

对于一般的高斯分布 xN(μ,σ2I)\mathbf{x} \sim \mathcal{N}(\boldsymbol{\mu}, \sigma^2\mathbf{I}),其概率密度函数为:

p(x)=1(2πσ2)d/2exp(xμ22σ2)p(\mathbf{x}) = \frac{1}{(2\pi\sigma^2)^{d/2}} \exp\left(-\frac{\|\mathbf{x} - \boldsymbol{\mu}\|^2}{2\sigma^2}\right)

取对数并对 x\mathbf{x} 求梯度(Score):

xlogp(x)=xμσ2\nabla_{\mathbf{x}} \log p(\mathbf{x}) = -\frac{\mathbf{x} - \boldsymbol{\mu}}{\sigma^2}

由于 x=μ+σϵ\mathbf{x} = \boldsymbol{\mu} + \sigma\boldsymbol{\epsilon},其中 ϵN(0,I)\boldsymbol{\epsilon} \sim \mathcal{N}(\mathbf{0}, \mathbf{I}),我们有:

xlogp(x)=σϵσ2=ϵσ\nabla_{\mathbf{x}} \log p(\mathbf{x}) = -\frac{\sigma\boldsymbol{\epsilon}}{\sigma^2} = -\frac{\boldsymbol{\epsilon}}{\sigma}

Step 3: 条件分布的 Score

将此结果应用于扩散模型。对于 q(xtx0)q(\mathbf{x}_t|\mathbf{x}_0),均值为 μ=αˉtx0\boldsymbol{\mu} = \sqrt{\bar{\alpha}_t}\mathbf{x}_0,标准差为 σ=1αˉt\sigma = \sqrt{1-\bar{\alpha}_t},因此条件分布的 Score 为:

xtlogq(xtx0)=ϵ1αˉt\nabla_{\mathbf{x}_t} \log q(\mathbf{x}_t|\mathbf{x}_0) = -\frac{\boldsymbol{\epsilon}}{\sqrt{1-\bar{\alpha}_t}}

Step 4: 从条件 Score 到边缘 Score(关键步骤)

我们想要的是边缘分布 q(xt)q(\mathbf{x}_t) 的 Score,而不是条件分布的 Score。边缘分布为:

q(xt)=q(xtx0)q(x0)dx0q(\mathbf{x}_t) = \int q(\mathbf{x}_t|\mathbf{x}_0) q(\mathbf{x}_0) d\mathbf{x}_0

对其求 Score:

xtlogq(xt)=xtq(xt)q(xt)=xtq(xtx0)q(x0)dx0q(xt)=q(xtx0)q(x0)q(xt)xtlogq(xtx0)dx0=q(x0xt)xtlogq(xtx0)dx0=Eq(x0xt)[xtlogq(xtx0)]\begin{aligned} \nabla_{\mathbf{x}_t} \log q(\mathbf{x}_t) &= \frac{\nabla_{\mathbf{x}_t} q(\mathbf{x}_t)}{q(\mathbf{x}_t)} = \frac{\int \nabla_{\mathbf{x}_t} q(\mathbf{x}_t|\mathbf{x}_0) q(\mathbf{x}_0) d\mathbf{x}_0}{q(\mathbf{x}_t)} \\ &= \int \frac{q(\mathbf{x}_t|\mathbf{x}_0) q(\mathbf{x}_0)}{q(\mathbf{x}_t)} \cdot \nabla_{\mathbf{x}_t} \log q(\mathbf{x}_t|\mathbf{x}_0) d\mathbf{x}_0 \\ &= \int q(\mathbf{x}_0|\mathbf{x}_t) \cdot \nabla_{\mathbf{x}_t} \log q(\mathbf{x}_t|\mathbf{x}_0) d\mathbf{x}_0 \\ &= \mathbb{E}_{q(\mathbf{x}_0|\mathbf{x}_t)}\left[\nabla_{\mathbf{x}_t} \log q(\mathbf{x}_t|\mathbf{x}_0)\right] \end{aligned}

代入条件 Score:

xtlogq(xt)=Eq(x0xt)[ϵ1αˉt]=Eq(x0xt)[ϵ]1αˉt\nabla_{\mathbf{x}_t} \log q(\mathbf{x}_t) = \mathbb{E}_{q(\mathbf{x}_0|\mathbf{x}_t)}\left[-\frac{\boldsymbol{\epsilon}}{\sqrt{1-\bar{\alpha}_t}}\right] = -\frac{\mathbb{E}_{q(\mathbf{x}_0|\mathbf{x}_t)}[\boldsymbol{\epsilon}]}{\sqrt{1-\bar{\alpha}_t}}

Step 5: 神经网络如何学习这个期望

在训练噪声预测网络 ϵθ(xt,t)\boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t) 时,损失函数为:

L=Eq(x0),ϵ[ϵϵθ(xt,t)2]L = \mathbb{E}_{q(\mathbf{x}_0), \boldsymbol{\epsilon}}\left[\|\boldsymbol{\epsilon} - \boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t)\|^2\right]

最小化均方误差的最优解恰好是条件期望

ϵθ(xt,t)=Eq(x0xt)[ϵ]\boldsymbol{\epsilon}_\theta^*(\mathbf{x}_t, t) = \mathbb{E}_{q(\mathbf{x}_0|\mathbf{x}_t)}[\boldsymbol{\epsilon}]

因此,训练好的神经网络隐式地学习了 Eq(x0xt)[ϵ]\mathbb{E}_{q(\mathbf{x}_0|\mathbf{x}_t)}[\boldsymbol{\epsilon}],从而:

xtlogq(xt)xtlogpθ(xt)ϵθ(xt,t)1αˉt\nabla_{\mathbf{x}_t} \log q(\mathbf{x}_t) \approx \nabla_{\mathbf{x}_t} \log p_\theta(\mathbf{x}_t) \approx -\frac{\boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t)}{\sqrt{1-\bar{\alpha}_t}}

这就建立了 Score 函数噪声预测网络之间的关系。

对于样本 xt\mathbf{x}_t 和标签 yy 联合分布的 Score 函数:

xtlog(pθ(xt)pϕ(yxt))=xtlogpθ(xt)+xtlogpϕ(yxt)ϵθ(xt,t)1αˉt+xtlogpϕ(yxt)=11αˉt(ϵθ(xt,t)1αˉtxtlogpϕ(yxt))\begin{aligned} \nabla_{\mathbf{x}_t} \log\left(p_\theta(\mathbf{x}_t) p_\phi(y|\mathbf{x}_t)\right) &= \nabla_{\mathbf{x}_t} \log p_\theta(\mathbf{x}_t) + \nabla_{\mathbf{x}_t} \log p_\phi(y|\mathbf{x}_t) \\ &\approx -\frac{\boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t)}{\sqrt{1-\bar{\alpha}_t}} + \nabla_{\mathbf{x}_t} \log p_\phi(y|\mathbf{x}_t) \\ &= -\frac{1}{\sqrt{1-\bar{\alpha}_t}}\left(\boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t) - \sqrt{1-\bar{\alpha}_t} \nabla_{\mathbf{x}_t} \log p_\phi(y|\mathbf{x}_t)\right) \end{aligned}

因此,新的分类引导噪声预测器为:

ϵˉθ(xt,t)=ϵθ(xt,t)1αˉtxtlogpϕ(yxt)\bar{\boldsymbol{\epsilon}}_\theta(\mathbf{x}_t, t) = \boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t) - \sqrt{1-\bar{\alpha}_t} \nabla_{\mathbf{x}_t} \log p_\phi(y|\mathbf{x}_t)

为了控制分类器引导的强度,添加一个权重 ss

ϵˉθ(xt,t)=ϵθ(xt,t)s1αˉtxtlogpϕ(yxt)\bar{\boldsymbol{\epsilon}}_\theta(\mathbf{x}_t, t) = \boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t) - s\sqrt{1-\bar{\alpha}_t} \nabla_{\mathbf{x}_t} \log p_\phi(y|\mathbf{x}_t)

由此产生的消融扩散模型 (Ablated Diffusion Model, ADM) 和带有附加分类器引导的模型 (ADM-G) 能够取得比 2022 年最好的 BigGAN 网络模型更好的结果。

Algorithm 2: Classifier Guided DDIM Sampling

Input: given a diffusion modelϵθ(xt),classifierpϕ(yxt),and gradient scales.xTN(0,I)for t=T,,1 doϵ^ϵθ(xt)s1αˉtxtlogpϕ(yxt)xt1αˉt1(xt1αˉtϵ^αˉt)+1αˉt1ϵ^end forreturn x0\begin{array}{l} \hline \textbf{Input: } \text{given a diffusion model} \epsilon_\theta\left(x_t\right), \text{classifier} p_\phi\left(y \mid x_t\right), \text{and gradient scale} s. \\ \hline \mathbf{x}_T \sim \mathcal{N}(\mathbf{0}, \mathbf{I}) \\ \textbf{for } t = T, \ldots, 1 \textbf{ do} \\ \quad \hat{\boldsymbol{\epsilon}} \leftarrow \boldsymbol{\epsilon}_\theta(\mathbf{x}_t) - s\sqrt{1-\bar{\alpha}_t} \nabla_{\mathbf{x}_t} \log p_\phi(y|\mathbf{x}_t) \\ \quad \mathbf{x}_{t-1} \leftarrow \sqrt{\bar{\alpha}_{t-1}}\left(\frac{\mathbf{x}_t - \sqrt{1-\bar{\alpha}_t}\hat{\boldsymbol{\epsilon}}}{\sqrt{\bar{\alpha}_t}}\right) + \sqrt{1-\bar{\alpha}_{t-1}}\hat{\boldsymbol{\epsilon}} \\ \textbf{end for} \\ \textbf{return } \mathbf{x}_0 \\ \hline \end{array}

评估指标

高层次上:

  • FID 和 sFID:捕获图像质量(越低越好)

  • 精度 (Precision):测量图像保真度(“与训练图像的相似度”)(越高越好)

  • 召回率 (Recall):衡量图像多样性/分布覆盖率(越高越好)

扩散模型击败GAN:样本质量对比

扩散模型与GAN的视觉效果对比

无分类器引导的动机与原理

分类器引导(Classifier Guidance)效果很好,但是有以下问题:

  • 无法直接使用预训练的分类器,因为分类器必须针对带噪声的样本进行专门训练;

  • 分类器引导将分类器的梯度注入到扩散模型训练过程,这导致模型是否真正学会了鲁棒性,还是仅仅像对抗攻击一样被梯度牵引,变得难以解释;

  • 为了避免这些困境,研究人员提出跳过外部分类器,同时联合训练条件和无条件扩散模型。 如果没有独立的分类器,我们仍然可以通过合并条件和无条件扩散模型的 score 梯度来进行引导。具体做法如下: 通过 score 估计器 ϵθ(xt,t)\boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t) 来参数化无条件去噪扩散模型 pθ(x)p_\theta(\mathbf{x}),并通过同样结构的神经网络添加条件,得到条件扩散模型 pθ(xy)p_\theta(\mathbf{x}|y)。这两个模型可以用同一个神经网络表示。我们通过在样本对 (x,y)(\mathbf{x}, y) 上训练条件扩散模型 pθ(xy)p_\theta(\mathbf{x}|y),并随机丢弃部分条件标签 yy,让模型学会无条件生成,即 ϵθ(xt,t)=ϵθ(xt,t,y=)\boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t) = \boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t, y = \emptyset)

隐式分类器的梯度 xtlogpθ(yxt)\nabla_{\mathbf{x}_t} \log p_\theta(y|\mathbf{x}_t) 可以用有条件 xtlogpθ(xty)\nabla_{\mathbf{x}_t} \log p_\theta(\mathbf{x}_t|y) 和无条件 score 估计器 xtlogpθ(xt)\nabla_{\mathbf{x}_t} \log p_\theta(\mathbf{x}_t) 来表示。如果将下面的噪声预测 ϵ^θ(xt,t,y)\hat{\epsilon}_\theta(\mathbf{x}_t, t, y) 运用到分类器引导的生成,那么整个生成过程都不依赖外部分类器。

推导如下: 首先,利用贝叶斯公式的对数形式: logpθ(yxt)=logpθ(xty)+logp(y)logpθ(xt)\log p_\theta(y|\mathbf{x}_t) = \log p_\theta(\mathbf{x}_t|y) + \log p(y) - \log p_\theta(\mathbf{x}_t)xt\mathbf{x}_t 求梯度得到:

xtlogpθ(yxt)=xtlogpθ(xty)xtlogpθ(xt)\nabla_{\mathbf{x}_t} \log p_\theta(y|\mathbf{x}_t) = \nabla_{\mathbf{x}_t} \log p_\theta(\mathbf{x}_t|y) - \nabla_{\mathbf{x}_t} \log p_\theta(\mathbf{x}_t)

而根据 score 匹配的定义,无条件 score 估计器可近似为:

xtlogpθ(xt)ϵθ(xt,t)1αˉt\nabla_{\mathbf{x}_t}\log p_\theta(\mathbf{x}_t) \approx - \frac{\epsilon_\theta(\mathbf{x}_t, t)}{\sqrt{1-\bar{\alpha}_t}}

同理,有条件 score 可近似为:

xtlogpθ(xty)ϵθ(xt,t,y)1αˉt\nabla_{\mathbf{x}_t}\log p_\theta(\mathbf{x}_t|y) \approx - \frac{\epsilon_\theta(\mathbf{x}_t, t, y)}{\sqrt{1-\bar{\alpha}_t}}

所以,

xtlogpθ(yxt)=xtlogpθ(xty)xtlogpθ(xt)=11αˉt[ϵθ(xt,t,y)ϵθ(xt,t)]\nabla_{\mathbf{x}_t} \log p_\theta(y|\mathbf{x}_t) = \nabla_{\mathbf{x}_t} \log p_\theta(\mathbf{x}_t|y) - \nabla_{\mathbf{x}_t} \log p_\theta(\mathbf{x}_t) = -\frac{1}{\sqrt{1-\bar{\alpha}_t}}\left[\epsilon_\theta(\mathbf{x}_t, t, y) - \epsilon_\theta(\mathbf{x}_t, t)\right]

将上式代入到新的分类引导预测器中,有:

ϵ^θ(xt,t,y)=ϵθ(xt,t,y)1αˉtsxtlogpθ(yxt)\hat{\epsilon}_\theta(\mathbf{x}_t, t, y) = \epsilon_\theta(\mathbf{x}_t, t, y) - \sqrt{1-\bar{\alpha}_t} s \nabla_{\mathbf{x}_t} \log p_\theta(y|\mathbf{x}_t)

=ϵθ(xt,t,y)+s(ϵθ(xt,t,y)ϵθ(xt,t))= \epsilon_\theta(\mathbf{x}_t, t, y) + s \left( \epsilon_\theta(\mathbf{x}_t, t, y) - \epsilon_\theta(\mathbf{x}_t, t) \right )

=(s+1)ϵθ(xt,t,y)  sϵθ(xt,t)= (s+1)\, \epsilon_\theta(\mathbf{x}_t, t, y)\ -\ s\, \epsilon_\theta(\mathbf{x}_t, t)

无分类器引导的优缺点分析

  • 无分类器引导的实现非常简单,而分类器引导则需要在噪声样本上训练外部分类器

  • 无分类器引导不采用任何类型的分类器梯度,不能被解释为对抗性攻击:它更符合 传统的生成模型

  • 无分类器引导比分类器引导慢,因为需要两倍的逆向扩散步骤

  • 两者都会降低样本多样性以提高样本保真度/质量

多样性(无引导样本,前两行)与保真度(有引导样本,后两行)

多样性(无引导样本,前两行)与保真度(有引导样本,后两行)

隐扩散模型

  • 在像素空间中训练模型的计算成本过高(在 V100 GPU 上可以轻松完 成数天)

    • 与 GAN 相比,即使是图像合成也非常慢

    • 图像是高维的 需要建模的东西更多

  • 通过观察,图像的大多数"位"都有助于其感知特征,因为积极压缩图像通常会保持其语义和概念组成

    • 通俗地说,用于描述像素级细节的位数较多,而用于描述图像内"含义"的位数较少

    • 生成模型应该学习后者

  • 我们可以将这两个组件分开吗?

隐扩散模型(Latent Diffusion Model,LDM;Rombach & Blattmann 等人,2022)在隐空间而非像素空间中运行扩散过程,这使得训练成本更低且推理速度更快。该方法的灵感来源于:图像中的大部分信息比特位用于表达感知细节,而在经过剧烈压缩后,其语义和概念结构依然能够得以保持。LDM通过生成式建模学习,大致上将感知压缩和语义压缩分开处理:首先利用自编码器去除像素级冗余,然后在习得的隐空间中通过扩散过程来操作/生成语义概念,从而实现这一目标。

感知压缩过程依赖于一个自编码器模型。该模型使用一个编码器 E\mathcal{E} 来将输入图像 xx 压缩成一个更小的二维隐向量 z=E(x)z=\mathcal{E}(x)。之后解码器 D\mathcal{D} 从这个隐向量中重构出图像,即 x~=D(z)\widetilde{x}=\mathcal{D}(z)

隐扩散模型分为两个阶段:

  1. 训练感知压缩模型,去除不相关的高级细节并学习语义上与高级图像像素空间等效的隐空间。

  2. 损失是重建损失、促进高质量解码器重建的对抗性损失(还记得 GAN 吗?)和正则化项的组合:

LAutoencoder=minE,Dmaxψ(Lrec(x,D(E(x)))Ladv(D(E(x)))+logDψ(x)+Lreg(x;E,D))L_{\mathrm{Autoencoder}} = \min_{\mathcal{E},\mathcal{D}} \max_{\psi} \left( L_{\mathrm{rec}}\left(x,\mathcal{D}\left(\mathcal{E}\left(x\right)\right)\right) - L_{\mathrm{adv}}\left(\mathcal{D}\left(\mathcal{E}\left(x\right)\right)\right) + \log D_\psi\left(x\right) + L_{\mathrm{reg}}\left(x;\mathcal{E},\mathcal{D}\right) \right)

在自编码器训练过程中,LDM 探索了两种正则化方法,以避免隐空间中出现任意高的方差。

  • KL 散度正则化(KL-reg):对学习的潜变量分布与标准正态分布进行小的 KL 惩罚,类似于 VAE。

  • 向量量化正则化(VQ-reg):在解码器内使用向量量化层,类似于 VQVAE,但量化层被解码器吸收。

交叉注意力机制的条件生成

扩散和去噪过程发生在隐向量 zz 上。去噪模型是一个时间条件化的 U-Net,通过加入交叉注意力机制来处理图像生成所需的灵活条件信息(例如,类别标签、语义地图、图像的模糊变体)。这种设计等同于利用交叉注意力机制将不同模态的表示融合到模型中。

每种类型的条件信息都与一个领域特定的编码器 τθ\tau_\theta 配对,该编码器用于将条件输入 yy 投影到一个中间表示,这个中间表示可以映射到交叉注意力组件中,即 τθ(y)\tau_\theta(y)

Attention(Q,K,V)=softmax(QKd)V\mathrm{Attention}(\mathbf{Q}, \mathbf{K}, \mathbf{V}) = \mathrm{softmax}\left(\frac{\mathbf{Q}\mathbf{K}^\top}{\sqrt{d}}\right)\cdot \mathbf{V}

其中:Q=WQ(i)φi(zi)\mathbf{Q} = \mathbf{W}_Q^{(i)}\cdot\varphi_i(\mathbf{z}_i)K=WK(i)τθ(y)\mathbf{K} = \mathbf{W}_K^{(i)} \cdot \tau_\theta(y)V=WV(i)τθ(y)\mathbf{V} = \mathbf{W}_V^{(i)} \cdot \tau_\theta(y)

在这个隐空间中进行扩散过程。这样做有几个好处:

  • 扩散过程仅关注样本的相关语义位

  • 在低维空间中执行扩散效率明显更高

扩散模型实例

from typing import Dict, Tuple
import torch
import torch.nn as nn


class DDPM(nn.Module):
    """
    去噪扩散概率模型 (Denoising Diffusion Probabilistic Model)
    register_buffer 允许我们通过名称自由访问这些张量。它有助于设备放置。
    """

    def __init__(self, eps_model: nn.Module, betas: Tuple[float, float], n_T: int, criterion: nn.Module = nn.MSELoss()) -> None:
        super(DDPM, self).__init__()
        self.eps_model = eps_model
        # register_buffer 允许我们通过名称自由访问这些张量。它有助于设备放置。
        for k, v in ddpm_schedules(betas[0], betas[1], n_T).items():
            self.register_buffer(k, v)
        self.n_T = n_T
        self.criterion = criterion

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        """进行正向扩散x_t,并尝试使用eps_model从x_t预测epsilon值。这实现了论文中的算法1。"""
        # t ~ Uniform(0, n_T)
        _ts = torch.randint(1, self.n_T + 1, (x.shape[0],)).to(x.device)
        eps = torch.randn_like(x)  # eps ~ N(0, 1)
        x_t = (self.sqrtab[_ts, None, None, None] * x
               + self.sqrtmab[_ts, None, None, None] * eps)
        # 运用噪声模型预测噪声,计算损失
        return self.criterion(eps, self.eps_model(x_t, _ts / self.n_T))
        
    def sample(self, n_sample: int, size, device) -> torch.Tensor:
        x_i = torch.randn(n_sample, *size).to(device)  # x_T ~ N(0, 1)
        # 根据算法2进行采样,逻辑完全相同。
        for i in range(self.n_T, 0, -1):
            z = torch.randn(n_sample, *size).to(device) if i > 1 else 0
            eps = self.eps_model(x_i, torch.tensor(i / self.n_T).to(device).repeat(n_sample, 1))
            x_i = (self.oneover_sqrta[i] * (x_i - eps * self.mab_over_sqrtmab[i])
                   + self.sqrt_beta_t[i] * z)
        return x_i

DDPM 训练算法

Algorithm 1: Trainingrepeatx0q(x0)从数据分布中采样tUniform({1,,T})随机选择时间步ϵN(0,I)采样高斯噪声梯度下降更新: θϵϵθ(αˉtx0+1αˉtϵ,t)2until converged\begin{array}{l} \textbf{Algorithm 1: Training} \\ \hline \textbf{repeat} \\ \quad \mathbf{x}_0 \sim q(\mathbf{x}_0) \quad \text{从数据分布中采样} \\ \quad t \sim \text{Uniform}(\{1, \ldots, T\}) \quad \text{随机选择时间步} \\ \quad \boldsymbol{\epsilon} \sim \mathcal{N}(\mathbf{0}, \mathbf{I}) \quad \text{采样高斯噪声} \\ \quad \text{梯度下降更新: } \nabla_\theta \left\|\boldsymbol{\epsilon} - \boldsymbol{\epsilon}_\theta\left(\sqrt{\bar{\alpha}_t}\mathbf{x}_0 + \sqrt{1-\bar{\alpha}_t}\boldsymbol{\epsilon}, t\right)\right\|^2 \\ \textbf{until converged} \end{array}

DDPM 采样算法(根据逆向分布采样公式)

Algorithm 2: SamplingxTN(0,I)从纯噪声开始for t=T,,1 dozN(0,I) if t>1, else z=0xt1=1αt(xt1αt1αˉtϵθ(xt,t))+σtzend forreturn x0\begin{array}{l} \textbf{Algorithm 2: Sampling} \\ \hline \mathbf{x}_T \sim \mathcal{N}(\mathbf{0}, \mathbf{I}) \quad \text{从纯噪声开始} \\ \textbf{for } t = T, \ldots, 1 \textbf{ do} \\ \quad \mathbf{z} \sim \mathcal{N}(\mathbf{0}, \mathbf{I}) \text{ if } t > 1 \text{, else } \mathbf{z} = \mathbf{0} \\ \quad \mathbf{x}_{t-1} = \frac{1}{\sqrt{\alpha_t}}\left(\mathbf{x}_t - \frac{1-\alpha_t}{\sqrt{1-\bar{\alpha}_t}}\boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t)\right) + \sigma_t\mathbf{z} \\ \textbf{end for} \\ \textbf{return } \mathbf{x}_0 \end{array}

DDPM实现:方差调度计算

def ddpm_schedules(beta1: float, beta2: float, T: int) -> Dict[str, torch.Tensor]:
    """为DDPM采样、训练过程预先计算的调度变量"""
    assert beta1 < beta2 < 1.0, "beta1 and beta2 must be in (0, 1)"
    beta_t = (beta2 - beta1) * torch.arange(0, T + 1, dtype=torch.float32) / T + beta1
    sqrt_beta_t = torch.sqrt(beta_t)
    alpha_t = 1 - beta_t
    log_alpha_t = torch.log(alpha_t)
    alphabar_t = torch.cumsum(log_alpha_t, dim=0).exp()
    sqrtab = torch.sqrt(alphabar_t)
    oneover_sqrta = 1 / torch.sqrt(alpha_t)
    sqrtmab = torch.sqrt(1 - alphabar_t)
    mab_over_sqrtmab_inv = (1 - alpha_t) / sqrtmab
    return {
        "alpha_t": alpha_t,
        "oneover_sqrta": oneover_sqrta,      # 1/sqrt(alpha_t)
        "sqrt_beta_t": sqrt_beta_t,
        "alphabar_t": alphabar_t,             # bar{alpha_t}
        "sqrtab": sqrtab,                     # sqrt(bar{alpha_t})
        "sqrtmab": sqrtmab,                   # sqrt(1-bar{alpha_t})
        "mab_over_sqrtmab": mab_over_sqrtmab_inv,  # (1-alpha_t)/sqrt(1-bar{alpha_t})
    }

DDIM实现:采样算法

xt1=αˉt1xt1αˉtϵθ(t)(xt)αˉt+1αˉt1σt2ϵθ(t)(xt)+σtϵ\mathbf{x}_{t-1} = \sqrt{\bar{\alpha}_{t-1}} \cdot \frac{\mathbf{x}_t - \sqrt{1-\bar{\alpha}_t}\boldsymbol{\epsilon}_\theta^{(t)}(\mathbf{x}_t)}{\sqrt{\bar{\alpha}_t}} + \sqrt{1-\bar{\alpha}_{t-1}-\sigma_t^2}\boldsymbol{\epsilon}_\theta^{(t)}(\mathbf{x}_t) + \sigma_t\boldsymbol{\epsilon}
σt(η)=η(1αˉtαˉs)1αˉs1αˉt\sigma_t(\eta) = \eta \cdot \sqrt{\left(1-\frac{\bar{\alpha}_t}{\bar{\alpha}_s}\right)\frac{1-\bar{\alpha}_s}{1-\bar{\alpha}_t}}
class DDIM(DDPM):

    def __init__(self, eps_model: nn.Module, betas: Tuple[float, float], eta: float, n_T: int, criterion: nn.Module = nn.MSELoss()) -> None:
        super(DDIM, self).__init__(eps_model, betas, n_T, criterion)
        self.eta = eta

    def sample(self, n_sample: int, size, device) -> torch.Tensor:
        x_i = torch.randn(n_sample, *size).to(device)  # x_T ~ N(0, 1)
        for i in range(self.n_T, 1, -1):
            eps_t = torch.randn(n_sample, *size).to(device) if i > 1 else 0
            eps = self.eps_model(x_i, torch.tensor(i / self.n_T).to(device).repeat(n_sample, 1))
            x0_t = (x_i - eps * (1 - self.alphabar_t[i]).sqrt()) / self.alphabar_t[i].sqrt()
            sigma = self.eta * ((1 - self.alphabar_t[i] / self.alphabar_t[i - 1]) * (1 - self.alphabar_t[i - 1]) / (1 - self.alphabar_t[i])).sqrt()
            c2 = ((1 - self.alphabar_t[i - 1]) - sigma ** 2).sqrt()
            x_i = self.alphabar_t[i - 1].sqrt() * x0_t + c2 * eps + sigma * eps_t
        return x_i

U-Net实现

"""Simple Unet Structure."""


class Conv3(nn.Module):

    def __init__(self, in_channels: int, out_channels: int, is_res: bool = False) -> None:
        super().__init__()
        self.main = nn.Sequential(
            nn.Conv2d(in_channels, out_channels, 3, 1, 1),
            nn.GroupNorm(8, out_channels),
            nn.ReLU())
        self.conv = nn.Sequential(
            nn.Conv2d(out_channels, out_channels, 3, 1, 1),
            nn.GroupNorm(8, out_channels),
            nn.ReLU(),
            nn.Conv2d(out_channels, out_channels, 3, 1, 1),
            nn.GroupNorm(8, out_channels),
            nn.ReLU())
        self.is_res = is_res

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        x = self.main(x)
        if self.is_res:
            x = x + self.conv(x)
            # 假设残差块的输入和输出具有相似的统计特性(例如,零均值和单位方差),
            # 那么添加两个这样的信号将导致方差加倍的信号。为了保持方差一致,您除以√2
            return x / 1.414
        else:
            return self.conv(x)

U-Net实现:下采样模块

class UnetDown(nn.Module):

    def __init__(self, in_channels: int, out_channels: int) -> None:
        super(UnetDown, self).__init__()
        layers = [Conv3(in_channels, out_channels), nn.MaxPool2d(2)]
        self.model = nn.Sequential(*layers)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        return self.model(x)

U-Net实现:上采样模块

卷积将各个像素中传播的信息累加到一个像素,而逆卷积则将一个像素中存在的信息传播到各个像素。

卷积将各个像素中传播的信息累加到一个像素,而逆卷积则将一个像素中存在的信息传播到各个像素。

class UnetUp(nn.Module):

    def __init__(self, in_channels: int, out_channels: int) -> None:
        super(UnetUp, self).__init__()
        layers = [
            nn.ConvTranspose2d(in_channels, out_channels, 2, 2),
            Conv3(out_channels, out_channels),
            Conv3(out_channels, out_channels),
        ]
        self.model = nn.Sequential(*layers)

    def forward(self, x: torch.Tensor, skip: torch.Tensor) -> torch.Tensor:
        x = torch.cat((x, skip), 1)
        x = self.model(x)
        return x

U-Net实现:时间嵌入模块

class TimeSiren(nn.Module):

    def __init__(self, emb_dim: int) -> None:
        super(TimeSiren, self).__init__()
        self.lin1 = nn.Linear(1, emb_dim, bias=False)
        self.lin2 = nn.Linear(emb_dim, emb_dim)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        x = x.view(-1, 1)
        x = torch.sin(self.lin1(x))  # sin来捕获周期
        x = self.lin2(x)
        return x

U-Net实现:U-Net网络结构

"""Simple Unet Structure."""


class NaiveUnet(nn.Module):

    def __init__(self, in_channels: int, out_channels: int, n_feat: int = 256) -> None:
        super(NaiveUnet, self).__init__()
        self.in_channels = in_channels
        self.out_channels = out_channels
        self.n_feat = n_feat

        self.init_conv = Conv3(in_channels, n_feat, is_res=True)
        self.down1 = UnetDown(n_feat, n_feat)
        self.down2 = UnetDown(n_feat, 2 * n_feat)
        self.down3 = UnetDown(2 * n_feat, 2 * n_feat)

        self.to_vec = nn.Sequential(nn.AvgPool2d(4), nn.ReLU())
        self.timeembed = TimeSiren(2 * n_feat)

        self.up0 = nn.Sequential(
            nn.ConvTranspose2d(2 * n_feat, 2 * n_feat, 4, 4),
            nn.GroupNorm(8, 2 * n_feat),
            nn.ReLU())
        self.up1 = UnetUp(4 * n_feat, 2 * n_feat)
        self.up2 = UnetUp(4 * n_feat, n_feat)
        self.up3 = UnetUp(2 * n_feat, n_feat)
        self.out = nn.Conv2d(2 * n_feat, self.out_channels, 3, 1, 1)

    def forward(self, x: torch.Tensor, t: torch.Tensor) -> torch.Tensor:
        x = self.init_conv(x)
        down1 = self.down1(x)
        down2 = self.down2(down1)
        down3 = self.down3(down2)

        thro = self.to_vec(down3)
        temb = self.timeembed(t).view(-1, self.n_feat * 2, 1, 1)
        thro = self.up0(thro + temb)

        up1 = self.up1(thro, down3) + temb
        up2 = self.up2(up1, down2)
        up3 = self.up3(up2, down1)

        out = self.out(torch.cat((up3, x), 1))
        return out

完整代码:CIFAR-10训练流程

from typing import Dict, Optional, Tuple
from tqdm import tqdm

import torch
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader
from torchvision.datasets import CIFAR10
from torchvision import transforms
from torchvision.utils import save_image, make_grid


def train_cifar10(n_epoch: int = 10, device: str = "cuda:0", load_pth: Optional[str] = None) -> None:
    # ddpm = DDPM(eps_model=NaiveUnet(3, 3, n_feat=128), betas=(1e-4, 0.02), n_T=1000)
    ddpm = DDIM(eps_model=NaiveUnet(3, 3, n_feat=128), betas=(1e-4, 0.02), eta=0.3, n_T=200)

    if load_pth is not None:
        ddpm.load_state_dict(torch.load("../../../data/diffusion_contents/ddpm_cifar.pth"))

    ddpm.to(device)

    tf = transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
    ])

    dataset = CIFAR10(
        "../../../dataset/cifar10",
        train=True,
        download=True,
        transform=tf)

    dataloader = DataLoader(dataset, batch_size=512, shuffle=True, num_workers=16)
    optim = torch.optim.Adam(ddpm.parameters(), lr=1e-5)

    for i in range(n_epoch):
        print(f"Epoch {i}:")
        ddpm.train()

        pbar = tqdm(dataloader)
        loss_ema = None

        for x, _ in pbar:
            optim.zero_grad()
            x = x.to(device)
            loss = ddpm(x)
            loss.backward()

            if loss_ema is None:
                loss_ema = loss.item()
            else:
                loss_ema = 0.9 * loss_ema + 0.1 * loss.item()

            pbar.set_description(f"loss: {loss_ema:.4f}")
            optim.step()

        ddpm.eval()
        with torch.no_grad():
            xh = ddpm.sample(8, (3, 32, 32), device)
            xset = torch.cat([xh, x[:8]], dim=0)
            grid = make_grid(xset, normalize=True, value_range=(-1, 1), nrow=4)
            save_image(grid, f"../../../data/diffusion_contents/ddpm_sample_cifar{i}.png")

            # save model
            torch.save(ddpm.state_dict(), f"../../../data/diffusion_contents/ddpm_cifar.pth")


if __name__ == "__main__":
    train_cifar10()
Epoch 0:
loss: 0.6317: 100%|██████████| 98/98 [00:39<00:00,  2.49it/s]
Epoch 1:
loss: 0.3541: 100%|██████████| 98/98 [00:38<00:00,  2.52it/s]
Epoch 2:
loss: 0.2534: 100%|██████████| 98/98 [00:38<00:00,  2.52it/s]
Epoch 3:
loss: 0.2081: 100%|██████████| 98/98 [00:38<00:00,  2.52it/s]
Epoch 4:
loss: 0.1876: 100%|██████████| 98/98 [00:39<00:00,  2.51it/s]
Epoch 5:
loss: 0.1710: 100%|██████████| 98/98 [00:39<00:00,  2.51it/s]
Epoch 6:
loss: 0.1604: 100%|██████████| 98/98 [00:38<00:00,  2.52it/s]
Epoch 7:
loss: 0.1546: 100%|██████████| 98/98 [00:39<00:00,  2.51it/s]
Epoch 8:
loss: 0.1469: 100%|██████████| 98/98 [00:38<00:00,  2.51it/s]
Epoch 9:
loss: 0.1437: 100%|██████████| 98/98 [00:39<00:00,  2.51it/s]
import matplotlib.pyplot as plt
from PIL import Image
import os

# CIFAR-10 class names
cifar10_classes = ['airplane', 'automobile', 'bird', 'cat', 'deer', 
                   'dog', 'frog', 'horse', 'ship', 'truck']

# Load and display the generated images
fig, axes = plt.subplots(2, 5, figsize=(15, 6))
fig.suptitle('DDPM Generated Samples on CIFAR-10', fontsize=16, fontweight='bold')

for i, ax in enumerate(axes.flatten()):
    img_path = f'../../../data/diffusion_contents/ddpm_sample_cifar{i}.png'
    if os.path.exists(img_path):
        img = Image.open(img_path)
        ax.imshow(img)
        ax.set_title(f'Class {i}: {cifar10_classes[i]}', fontsize=10)
    ax.axis('off')

plt.tight_layout()
plt.show()
<Figure size 1500x600 with 10 Axes>

典型扩散模型应用概述

DALL-E 2:文本到图像生成

Imagen:高质量文本到图像生成

Video Diffusion:文本到视频生成

文本生成3D模型:Dreamfusion

Diffusion-QL:离线强化学习

甚至适用于 RL !

  • 回想一下,扩散基本上 是一种学习未知分布的方法。

  • 在离线强化学习中,目 标是从离线样本集中训练智能体

参考资源与延伸阅读

其他资源:

小结

本章系统地介绍了扩散模型(Diffusion Models)的理论基础、改进方法、实现细节和应用场景。

核心概念

去噪扩散概率模型(DDPM) 是扩散模型的基础框架,包含两个过程:

  • 正向扩散过程:通过逐步添加高斯噪声将数据分布转换为标准正态分布

    q(xtx0)=N(xt;αˉtx0,(1αˉt)I)q(\mathbf{x}_t|\mathbf{x}_0) = \mathcal{N}(\mathbf{x}_t; \sqrt{\bar{\alpha}_t}\mathbf{x}_0, (1-\bar{\alpha}_t)\mathbf{I})
  • 逆向去噪过程:学习从噪声中逐步恢复原始数据

    pθ(xt1xt)=N(xt1;μθ(xt,t),Σθ(xt,t))p_\theta(\mathbf{x}_{t-1}|\mathbf{x}_t) = \mathcal{N}(\mathbf{x}_{t-1}; \boldsymbol{\mu}_\theta(\mathbf{x}_t, t), \boldsymbol{\Sigma}_\theta(\mathbf{x}_t, t))

训练目标:简化损失函数通过预测噪声 ϵ\boldsymbol{\epsilon} 来学习逆向过程:

Lsimple=Et,x0,ϵ[ϵϵθ(xt,t)2]L_{\text{simple}} = \mathbb{E}_{t, \mathbf{x}_0, \boldsymbol{\epsilon}}\left[\|\boldsymbol{\epsilon} - \boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t)\|^2\right]

模型改进

改进方法核心思想优势
DDIM非马尔可夫采样过程加速采样(50-100步 vs 1000步)
IDDPM学习方差 Σθ\boldsymbol{\Sigma}_\theta + 混合损失提升对数似然
分类器引导利用分类器梯度引导采样提高生成保真度
无分类器引导联合训练条件/无条件模型无需额外分类器
隐扩散模型在潜在空间进行扩散降低计算成本

关键公式

Score 函数与噪声预测的关系

xtlogp(xt)=ϵθ(xt,t)1αˉt\nabla_{\mathbf{x}_t} \log p(\mathbf{x}_t) = -\frac{\boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t)}{\sqrt{1-\bar{\alpha}_t}}

分类器引导的采样

ϵˉθ(xt,t)=ϵθ(xt,t)w1αˉtxtlogpϕ(yxt)\bar{\boldsymbol{\epsilon}}_\theta(\mathbf{x}_t, t) = \boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t) - w\sqrt{1-\bar{\alpha}_t} \nabla_{\mathbf{x}_t} \log p_\phi(y|\mathbf{x}_t)

无分类器引导

ϵ~θ(xt,t,y)=(1+w)ϵθ(xt,t,y)wϵθ(xt,t)\tilde{\boldsymbol{\epsilon}}_\theta(\mathbf{x}_t, t, y) = (1+w)\boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t, y) - w\boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t)

实现要点

  1. U-Net 架构:扩散模型通常采用 U-Net 作为噪声预测网络,结合时间嵌入、残差块和注意力机制

  2. 方差调度:线性或余弦调度控制噪声添加的节奏

  3. 条件生成:通过交叉注意力机制融入文本、类别等条件信息

典型应用

  • 文本到图像:DALL-E 2、Imagen、Stable Diffusion

  • 文本到视频:Video Diffusion Models

  • 3D 生成:DreamFusion、Magic3D

  • 强化学习:Diffusion-QL

与其他生成模型的对比

特性扩散模型GANVAE
训练稳定性✓ 稳定✗ 模式坍塌✓ 稳定
样本质量✓ 高质量✓ 高质量△ 模糊
采样速度✗ 慢(需迭代)✓ 快✓ 快
多样性✓ 高△ 有限✓ 高
对数似然✓ 可计算✗ 不可计算△ 下界

扩散模型凭借其稳定的训练过程、高质量的生成结果和灵活的条件控制能力,已成为当前最具影响力的生成模型范式之一。

🤖