\[ \begin{align}\begin{aligned}\newcommand{\ba}{\boldsymbol{a}} \newcommand{\bb}{\boldsymbol{b}} \newcommand{\be}{\boldsymbol{e}} \newcommand{\bq}{\boldsymbol{q}} \newcommand{\bk}{\boldsymbol{k}} \newcommand{\bw}{\boldsymbol{w}} \newcommand{\bx}{\boldsymbol{x}} \newcommand{\by}{\boldsymbol{y}} \newcommand{\bz}{\boldsymbol{z}} \newcommand{\bd}{\boldsymbol{d}} \newcommand{\bv}{\boldsymbol{v}} \newcommand{\bs}{\boldsymbol{s}}\\\newcommand{\btheta}{\boldsymbol{\theta}} \newcommand{\bbeta}{\boldsymbol{\beta}} \newcommand{\bgamma}{\boldsymbol{\gamma}} \newcommand{\bsigma}{\boldsymbol{\sigma}} \newcommand{\md}{\mbox{d}} \newcommand{\bmu}{\boldsymbol{\mu}} \newcommand{\bone}{\boldsymbol{1}} \newcommand{\bzero}{\boldsymbol{0}} \newcommand{\bepsilon}{\boldsymbol{\epsilon}} \newcommand{\bphi}{\boldsymbol{\phi}} \newcommand{\bh}{\boldsymbol{h}} \newcommand{\bc}{\boldsymbol{c}} \newcommand{\br}{\boldsymbol{r}} \newcommand{\bQ}{\boldsymbol{Q}} \newcommand{\bK}{\boldsymbol{K}} \newcommand{\bV}{\boldsymbol{V}} \newcommand{\bSigma}{\boldsymbol{\Sigma}} \newcommand{\bg}{\boldsymbol{g}} \newcommand{\bxi}{\boldsymbol{\xi}} \newcommand{\bvarepsilon}{\boldsymbol{\varepsilon}} \newcommand{\bdelta}{\boldsymbol{\delta}} \newcommand{\bq}{\boldsymbol{q}} \newcommand{\bk}{\boldsymbol{k}} \newcommand{\bJ}{\boldsymbol{J}} \newcommand{\bp}{\boldsymbol{p}} \newcommand{\bi}{\boldsymbol{i}} \newcommand{\bo}{\boldsymbol{o}} \newcommand{\bE}{\boldsymbol{E}} \newcommand{\bH}{\boldsymbol{H}} \newcommand{\bL}{\boldsymbol{L}} \newcommand{\bu}{\boldsymbol{u}} \newcommand{\bLambda}{\boldsymbol{\Lambda}} \newcommand{\trans}{^{\rm\scriptsize T}} \newcommand{\var}{\mathrm{var}}\\\newcommand{\bA}{\boldsymbol{A}} \newcommand{\bB}{\boldsymbol{B}} \newcommand{\bC}{\boldsymbol{C}} \newcommand{\bD}{\boldsymbol{D}} \newcommand{\bG}{\boldsymbol{G}} \newcommand{\bI}{\boldsymbol{I}} \newcommand{\bM}{\boldsymbol{M}} \newcommand{\bP}{\boldsymbol{P}} \newcommand{\bS}{\boldsymbol{S}} \newcommand{\bU}{\boldsymbol{U}} \newcommand{\bW}{\boldsymbol{W}} \newcommand{\bX}{\boldsymbol{X}} \newcommand{\bY}{\boldsymbol{Y}} \newcommand{\bZ}{\boldsymbol{Z}} \newcommand{\cotp}{\textcolor[RGB]{48,209,88}{TP}} \newcommand{\cotn}{\textcolor[RGB]{100,210,255}{TN}} \newcommand{\cofp}{\textcolor[RGB]{94,92,230}{FP}} \newcommand{\cofn}{\textcolor[RGB]{191,90,242}{FN}}\\\newcommand{\numcotp}{\textcolor[RGB]{48,209,88}{50}} \newcommand{\numcotn}{\textcolor[RGB]{100,210,255}{30}} \newcommand{\numcofp}{\textcolor[RGB]{94,92,230}{10}} \newcommand{\numcofn}{\textcolor[RGB]{191,90,242}{10}} \DeclareMathOperator*{\argmin}{arg\,min}\end{aligned}\end{align} \]

基于分数的扩散模型与随机微分方程#

学习目标与记号#

  1. 解释分数函数(score function)的几何意义,并由去噪分数匹配构造可训练目标;

  2. 理解 NCSN 的多噪声尺度与退火 Langevin 动力学;

  3. 用随机微分方程(stochastic differential equation,SDE)统一 VP、VE 扩散,并区分反向 SDE 与概率流 ODE;

  本节沿用统一记号:普通小写字母表示标量,粗体小写字母表示向量,粗体大写字母表示矩阵或高阶张量;时间步写作下标 \(t\)⁠,网络层编号写作上标 \([l]\)⁠,转置写作 \(\trans\)⁠。\(\bx_0\) 表示干净数据,\(\bx_t\) 表示第 \(t\) 个噪声等级的随机变量。一般的标准高斯扰动记作 \(\bepsilon\)⁠;离散前向过程中,从 \(\bx_{t-1}\) 得到 \(\bx_t\) 时单独加入的噪声记作 \(\bepsilon_t\)⁠;解析重参数化中直接由 \(\bx_0\) 构造 \(\bx_t\) 的累计噪声记作 \(\tilde{\bepsilon}_t\)⁠。这里,\(\tilde{\bepsilon}_t\) 是前 \(t\) 步单步噪声按相应系数合并并标准化后得到的等价标准高斯变量,不是把这些噪声直接相加。正文与练习中的程序都应同时检查数值结果和数组维度。本节练习的参考答案见 分数模型与扩散 SDE 答案⁠。

  上一节的 DDPM 用"预测噪声"来学习生成:网络输出累计等价噪声的估计 \(\bepsilon_{\btheta}(\bx_t,t)\)⁠,并按解析式在离散时间步上逐步去噪。本节换一个看待同一问题的角度:不去建模密度函数 \(p(\bx)\) 本身,而是估计它的"坡度",即对数密度的梯度 \(\nabla_{\bx}\log p(\bx)\)⁠;这个梯度向量场被称为 分数⁠。选择分数的原因有两点。第一,对数密度加上任意常数都不会改变它的梯度,因此分数在归一化常数未知时也能定义和学习;而在高维空间中,直接归一化一个未归一化的密度需要计算高维积分,几乎不可行,估计一个与数据同维的向量场却可以交给神经网络用回归目标完成。第二,分数在每个位置都指向密度上升最快的方向,知道分数就等于知道"哪里更可能有数据",这为采样提供了直接的导航信息。因此,两条路线的根本区别在于:DDPM 把生成问题拆成"预测噪声、逐步去噪",分数路线把它拆成"估计密度梯度、沿梯度移动"。

  两条路线并不是互不相干的两个算法。在线性高斯扰动下,加噪条件分布 \(q(\bx_t\mid\bx_0)\) 的分数与解析式中的累计等价噪声 \(\tilde{\bepsilon}_t\) 只差一个已知的尺度因子和负号,因此上一节的噪声预测网络稍加换算就可以当作分数网络使用,分数估计也可以反过来换算成噪声预测。换句话说,\(\bepsilon_{\btheta}(\bx_t,t)\)\(\bs_{\btheta}(\bx_t,t)\) 只是同一个"网络该学什么"的两种参数化,两者共享"逐步加噪、逐步去噪"的骨架;区别主要体现在采样与理论框架上:DDPM 在离散时间步上按解析式更新,分数路线则用连续时间的 Langevin 动力学或随机微分方程描述同样的过程,更容易推广到不同的噪声方案,并用统一的数学语言分析收敛与采样误差。基于分数的生成模型(score-based generative model) 1Song 与 Ermon(2019)⁠,Generative Modeling by Estimating Gradients of the Data Distribution⁠;Song 等(2021)⁠,Score-Based Generative Modeling through Stochastic Differential Equations⁠。 正是在这一视角下发展起来的。

  要在分数路线上完成生成,需要依次解决三个问题,本节的三个主题正是围绕它们展开:如何定义分数⁠:对任意具有可微密度的分布,分数就是其对数密度的梯度,这一部分在"分数函数"中给出定义与几何意义;如何学习分数⁠:真实数据分布未知,直接回归分数不可行,去噪分数匹配指出可以用加噪条件分布的分数作为监督——给定干净样本和噪声时,该条件分数可以直接算出,从而把未知目标换成可计算目标,这一部分在"去噪分数匹配"中完成;如何用分数采样⁠:分数只给出方向,还需要沿方向移动的算法,Langevin 动力学正是这样一类带噪声的迭代采样过程,而数据往往集中在低维流形附近,单一噪声尺度下远离数据的区域几乎没有可靠的分数信号,因此 NCSN 在多个递减的噪声尺度上训练同一个网络,并用退火 Langevin 动力学完成采样,这一部分在"NCSN 与退火 Langevin 动力学"中介绍。最后的 SDE 统一视角 把离散加噪推广到连续时间:正向 SDE 描述加噪过程,反向 SDE 以分数作为漂移项完成去噪,概率流 ODE 则给出边缘分布相同的确定性版本。

  本节数学推导较多、记号较密,建议读者先抓住上面这条主线(定义 → 学习 → 采样 → 统一),再逐节对照公式阅读;正文中的程序与 综合练习 可以帮助核验每一步的理解。

分数函数#

分数向量场、Langevin 采样以及正向和反向随机微分方程

图 43 分数指向高密度方向;不同噪声尺度让采样从平滑分布逐步过渡到数据分布#

  在图 图 43 中,\(p_t(\bx)\) 表示第 \(t\) 个噪声等级下加噪样本 \(\bx_t\) 的边缘分布,即把加噪条件分布对干净数据 \(\bx_0\) 取平均得到的分布 \(p_t(\bx)=\int q(\bx\mid\bx_0)p(\bx_0)\,\mathrm{d}\bx_0\)⁠。对具有可微密度的分布 \(p_t(\bx)\)⁠,分数(score)定义为

\[\bs^{\star}(\bx,t) =\nabla_{\bx}\log p_t(\bx).\]

它是与 \(\bx\) 同维的向量场,指向对数密度增长最快的方向。这里的上标 \(\star\) 强调它是真实(理想)分数,以区别于后面将要学习并用于采样的参数化分数 \(\bs_{\btheta}(\bx,t)\)⁠。分数不需要知道归一化常数:若 \(p(\bx)=\tilde p(\bx)/Z\)⁠,则 \(\nabla_{\bx}\log p(\bx)=\nabla_{\bx}\log\tilde p(\bx)\)⁠。这一点使它适合描述高维能量分布。

  直接获得真实数据分数通常很困难,而且数据可能集中在低维流形附近。向数据加入高斯噪声可使分布更平滑。对扰动核

\[q_\sigma(\tilde\bx\mid\bx_0) =\mathcal{N}(\bx_0,\sigma^2\bI),\]

其条件分数可直接计算:

\[\nabla_{\tilde\bx} \log q_\sigma(\tilde\bx\mid\bx_0) =-\frac{\tilde\bx-\bx_0}{\sigma^2} =-\frac{\bepsilon}{\sigma}.\]

去噪分数匹配#

  分数模型面对一个现实问题:真实数据分布 \(p(\bx)\) 的密度并不知道,直接估计其分数 \(\nabla_{\bx}\log p(\bx)\) 缺少监督信号;而且真实数据常集中在低维流形附近,那里的分数难以定义或数值不稳定。 去噪分数匹配 (denoising score matching,DSM) 2Vincent(2011) 提出去噪分数匹配,并证明它与显式分数匹配的联系;Song 与 Ermon(2019) 将其与多噪声尺度(NCSN)结合用于生成模型。 的解决办法是:先给数据加上已知的高斯噪声使分布平滑,再把 扰动核的条件分数 当作训练目标——它只依赖干净样本和噪声,可以精确计算,因而不需要知道未知的边缘分数。这样,网络就能在不知道真实密度的情况下近似扰动分布的分数 \(\nabla_{\tilde\bx}\log p_\sigma(\tilde\bx)\)⁠。

  设扰动核 \(q_\sigma(\tilde\bx\mid\bx_0)\) 为正态分布 \(\mathcal{N}(\bx_0,\sigma^2\bI)\) 的概率密度函数,其中 \(\bx_0\) 是干净样本,\(\tilde\bx\) 是加噪后的样本,\(\sigma>0\) 是噪声尺度(标准差)。对 \(\bx_0\) 取平均得到扰动后的边缘分布 \(p_\sigma(\tilde\bx)=\int q_\sigma(\tilde\bx\mid\bx_0)p(\bx_0)\,\mathrm{d}\bx_0\)⁠。如 分数函数 一节所推导,高斯扰动的条件分数为

\[\nabla_{\tilde\bx}\log q_\sigma(\tilde\bx\mid\bx_0) =-\frac{\tilde\bx-\bx_0}{\sigma^2} =-\frac{\bepsilon}{\sigma}, \qquad \tilde\bx=\bx_0+\sigma\bepsilon, \quad \bepsilon\sim\mathcal{N}(\bzero,\bI),\]

它把"未知的边缘分数"换成了"已知的条件分数":给定任意干净样本 \(\bx_0\) 和采样出的噪声 \(\bepsilon\)⁠,右边每一项都能直接算出。让分数网络 \(\bs_{\btheta}(\tilde\bx,\sigma)\) (输入是加噪样本和噪声尺度,输出是与 \(\tilde\bx\) 同维的预测分数,\(\btheta\) 是网络参数)逼近这个条件分数,得到去噪分数匹配目标

\[\mathcal{L}_{\mathrm{DSM}} =\mathbb{E}_{\bx_0,\sigma,\bepsilon} \left[ \lambda(\sigma) \left\| \bs_{\btheta}(\bx_0+\sigma\bepsilon,\sigma) +\frac{\bepsilon}{\sigma} \right\|_2^2 \right],\]

其中,期望 \(\mathbb{E}_{\bx_0,\sigma,\bepsilon}\) 表示对三个随机量同时取平均:干净样本 \(\bx_0\) 按数据分布抽取,噪声尺度 \(\sigma\) 按预先设定的分布抽取,例如对数均匀或一组离散值;,标准高斯噪声 \(\bepsilon\) 独立抽取;范数 \(\lVert\cdot\rVert_2^2\) 表示逐元素求差后平方求和,因此整个目标衡量"预测分数与条件分数之间的平方平均损失"。括号里的 \(\bx_0+\sigma\bepsilon\) 就是按重参数化生成的加噪样本 \(\tilde\bx\)⁠。

  权重的作用。 条件分数 \(-\bepsilon/\sigma\) 的范数约为 \(\sqrt{d}/\sigma\)⁠,其中 \(d\) 是数据维数,因此 \(\sigma\) 越小,目标项天然越大。若取 \(\lambda(\sigma)=1\)⁠,小噪声样本会主导梯度,网络倾向于只顾最平滑的小尺度结构,忽略大噪声对应的整体形状。\(\lambda(\sigma)\) 就是按噪声尺度重新标定各项的权重函数;常见选择是 \(\lambda(\sigma)=\sigma^2\)⁠,此时各项的期望尺度与 \(\sigma\) 无关,且目标退化为"预测噪声 \(\bepsilon\)"的均方误差形式,与 DDPM 的简化损失同构,具体代数见本节 综合练习⁠。\(\lambda(\sigma)\) 的具体形式属于需要与噪声尺度分布、采样器配套选择的设计,应在实验中固定并报告。

  与显式分数匹配的关系。 理想情况下我们希望网络逼近未知的边缘分数 \(\nabla_{\tilde\bx}\log p_\sigma(\tilde\bx)\)⁠,对应显式分数匹配目标 \(\mathcal{L}_{\mathrm{SM}}=\mathbb{E}_{\tilde\bx}\left[\frac{1}{2}\left\|\bs_{\btheta}(\tilde\bx,\sigma)-\nabla_{\tilde\bx}\log p_\sigma(\tilde\bx)\right\|_2^2\right]\)⁠。去噪目标之所以能替代它,是因为在适当正则条件下,把平方展开后 \(\mathcal{L}_{\mathrm{DSM}}\)\(\mathcal{L}_{\mathrm{SM}}\) 只相差一个与 \(\btheta\) 无关的常数,因而两者对 \(\btheta\) 有相同的最优解:其中的交叉项通过分部积分可改写为与边缘分数有关的形式,具体证明见本节 综合练习⁠。这也是"用可计算的条件分数当监督"能够替代"未知的真分数"的原因。

  对 DDPM 的方差保持扰动

\[\bx_t=\sqrt{\bar\alpha_t}\bx_0 +\sqrt{1-\bar\alpha_t}\tilde{\bepsilon}_t,\]

其中累计噪声的标准差即该时刻的噪声尺度 \(\sigma_t=\sqrt{1-\bar\alpha_t}\)⁠,条件分数为

\[\nabla_{\bx_t}\log q(\bx_t\mid\bx_0) =-\frac{\tilde{\bepsilon}_t}{\sigma_t} =-\frac{\tilde{\bepsilon}_t}{\sqrt{1-\bar\alpha_t}}.\]

因此可以由前面定义的 DDPM 噪声预测网络 构造分数估计

\[\bs_{\btheta}(\bx_t,\sigma_t) =-\frac{\bepsilon_{\btheta}(\bx_t,t)} {\sigma_t} =-\frac{\bepsilon_{\btheta}(\bx_t,t)} {\sqrt{1-\bar\alpha_t}}.\]

这里,\(\bepsilon_{\btheta}(\bx_t,t)\) 估计的是解析式中的累计噪声 \(\tilde{\bepsilon}_t\)⁠,而不是第 \(t\) 步单独加入的 \(\bepsilon_t\)⁠。这个转换关系说明:在线性高斯扰动下, 预测噪声预测分数 只是同一个网络的两种参数化,二者相差一个已知的尺度因子 \(1/\sigma_t=1/\sqrt{1-\bar\alpha_t}\) 和负号。分数网络的第二个输入始终是 噪声尺度 :在连续尺度设定下记作 \(\sigma\)⁠,在 DDPM 的离散时间步上记作对应的 \(\sigma_t\)⁠,二者含义一致,只是记号不同。

NCSN 与退火 Langevin 动力学#

  前面说过,直接估计真实数据的分数很困难,原因之一是数据往往集中在低维流形附近:远离流形的区域密度几乎为 0,那里的对数密度没有可靠定义,分数(对数密度的梯度)也就失去信号。给数据加上高斯噪声后,扰动分布处处有正密度,分数处处有定义且数值稳定,这正是去噪分数匹配的出发点。但噪声尺度本身需要权衡:\(\sigma\) 太小时,分布仍然贴近数据流形,远离数据的区域依旧"无信号",从那里出发的采样得不到有效指引;\(\sigma\) 太大时,分布被过度抹平,丢失数据的精细结构,采出的样本只有大致轮廓。单一噪声尺度无法同时兼顾"处处可靠"与"保留细节"⁠。

  噪声条件分数网络(noise conditional score network,NCSN)的解决办法是:不追求某个"最优"的单一尺度,而是让同一个网络同时逼近一组不同噪声尺度下的分数。具体地,选定一组递减的噪声尺度 \(\sigma_1>\sigma_2>\cdots>\sigma_L\)⁠,通常按几何级数递减、跨越多个数量级;分数网络 \(\bs_{\btheta}(\bx,\sigma)\) 把噪声尺度作为第二个输入;去噪分数匹配目标对 \(i=1,\ldots,L\) 的每个尺度分别取期望再求和(或取平均),使网络在每个 \(\sigma_i\) 上都能给出对应的分数估计。大尺度下的分数负责"整体形状":分布平滑、信号处处可靠,采样器可以在其中自由移动;小尺度下的分数负责"精细细节":分布接近真实数据,可以恢复出清晰的样本。

记号辨析:噪声尺度 \(\sigma_i\) 与单步加噪方差 \(\beta_t\)

  上一节以及 扩散随机变量与逐步加噪参数 都用 \(\beta_t\) 描述前向过程第 \(t\)单独加入 的噪声方差:一步转移 \(q(\bx_t\mid\bx_{t-1})=\mathcal{N}(\sqrt{\alpha_t}\bx_{t-1},\beta_t\bI)\)⁠,其中 \(0<\beta_t<1\) 且通常很小;\(T\) 是把干净数据变成(近似)纯噪声所需的 离散时间步数⁠,前向与反向都沿这条链逐时间步进行。这里的 \(\sigma_i\) 则是第 \(i\) 个噪声等级的 扰动标准差⁠:它直接描述"与干净样本相比,加噪样本被扰动了多大幅度",即 \(\tilde\bx=\bx_0+\sigma_i\bepsilon\)⁠、\(q_{\sigma_i}(\tilde\bx\mid\bx_0)=\mathcal{N}(\bx_0,\sigma_i^2\bI)\)⁠;\(L\) 是训练与采样所用的 噪声等级个数⁠,它与 \(T\) 相互独立,通常远小于 \(T\)⁠,例如 DDPM 常用 \(T=1000\)⁠、NCSN 常用 \(L\) 在 10--50 之间;并且每个尺度上还可以再跑若干步 Langevin 更新。

  两者的联系在于:在 DDPM 的方差保持扰动下,第 \(t\) 步相对干净样本的累计噪声标准差正是由 \(\beta_1,\ldots,\beta_t\) 累积而来的 \(\sqrt{1-\bar\alpha_t}\)⁠,它扮演的角色与 \(\sigma_i\) 相同;若取 \(\sigma_i^2=1-\bar\alpha_{t_i}\)⁠,NCSN 的尺度序列与 DDPM 的时间阶梯一一对应。区别在于:DDPM 用 逐时间步的小方差 \(\beta_t\) 描述"每一步加多少噪声",累计噪声及其标准差是推导出来的结果;NCSN 则 直接指定 扰动标准差 \(\sigma_i\)⁠,不经过逐小步累积,也不要求尺度序列来自某个 \(\beta\) 序列。这种"直接控制方差"的设定对应后文 SDE 视角中的方差爆炸(VE)方案,而 DDPM 的 \(\bar\alpha_t\) 对应方差保持(VP)方案。此外,\(T\) 由前向过程的定义决定,是过程本身的一部分;\(L\) 以及每个尺度的 Langevin 步数都属于训练与采样器的 设计选择——改变 \(L\) 不需要改变前向加噪的定义,只要训练时使用的尺度与采样时一致即可。

  有了多尺度的分数网络,还需要一个把分数向量场转化为样本的算法。Langevin 动力学 (Langevin dynamics)是其中最基本的迭代采样过程:固定噪声尺度 \(\sigma\)⁠,从任意起点出发反复执行

\[\bx^{(k+1)} =\bx^{(k)}+\frac{\eta}{2} \bs_{\btheta}(\bx^{(k)},\sigma) +\sqrt{\eta}\bz^{(k)}, \qquad \bz^{(k)}\sim\mathcal{N}(\bzero,\bI).\]

其中,\(\eta>0\) 是步长,\(\bz^{(k)}\sim\mathcal{N}(\bzero,\bI)\) 是每次更新独立抽取的标准高斯噪声。更新式由两项组成:第一项 \((\eta/2)\bs_{\btheta}(\bx^{(k)},\sigma)\) 沿分数方向移动——分数指向对数密度上升最快的方向,因此这一项相当于对对数密度做步长为 \(\eta/2\) 的梯度上升,把样本推向高密度区域;第二项加入尺度为 \(\sqrt{\eta}\) 的标准高斯随机扰动,它保证链不会坍缩到某个局部峰,而是持续探索,两项平衡后链的平稳分布恰好是扰动分布 \(p_\sigma(\tilde\bx)\)⁠,即去噪分数匹配一节定义的加噪样本边缘分布 \(p_\sigma(\tilde\bx)=\int q_\sigma(\tilde\bx\mid\bx_0)p(\bx_0)\,\mathrm{d}\bx_0\)⁠。需要说明的是,这一"恰好"结论对连续时间 Langevin 动力学严格成立,有限步长 \(\eta\) 下,离散链的平稳分布与 \(p_\sigma(\tilde\bx)\) 相差 \(O(\eta)\) 阶,只有步长趋于 0 时才精确回到 \(p_\sigma(\tilde\bx)\)⁠。可以这样理解:梯度项决定"往哪里走",噪声项决定"走的时候保留多少随机性"。实际中只能做有限次迭代,因此存在两类误差:步长过大带来的离散误差,可能使更新失真甚至发散;以及迭代次数不足带来的收敛误差,链尚未到达平稳分布;步长、每个噪声尺度的迭代次数与最终残余噪声都会影响偏差和成本,不能把网络分数正确等同于任意步长下都能精确采样。

  退火 Langevin 动力学 把多尺度网络与 Langevin 更新组合成完整的采样过程:先取最大的尺度 \(\sigma_1\)⁠,在该尺度上运行 \(K\) 步 Langevin 更新,此时分布最平滑,样本可以自由探索整体结构;再换到下一个尺度 \(\sigma_2\) 继续运行 \(K\) 步,依此类推直到最小的尺度 \(\sigma_L\)⁠。每换一次尺度,样本应服从的分布从较平滑的 \(p_{\sigma_i}\) 收紧到更接近数据的 \(p_{\sigma_{i+1}}\)⁠;样本沿着一串逐渐逼近真实数据分布的中间分布移动,由粗到细地接近目标,这就是"退火"的含义。整个过程把"从数据分布采样"分解成 \(L\) 个相对容易的子任务:每一步只需在当前平滑程度下移动样本,而不是一步从纯噪声跳到清晰图像。采样结束时,样本中还会残留尺度约为 \(\sigma_L\) 的噪声,因此通常把 \(\sigma_L\) 取得足够小,但仍要保证该尺度下分数可靠,使残留噪声不影响生成质量。总网络调用次数为 \(L\times K\)⁠,即 网络评估次数 (number of function evaluations,NFE),比较不同配置时应同时报告 \(L\)⁠、\(K\) 与总 NFE。

  与 DDPM 的采样相比:DDPM 每个时间步调用网络一次,共 \(T\) 次;NCSN 每个尺度调用网络 \(K\) 次,共 \(L\times K\) 次;DDPM 的噪声水平由 \(\beta_t\) 的累积决定,NCSN 则直接指定 \(\sigma_i\)⁠。下一节的 SDE 统一视角 会说明,把 \(\beta_t\)\(\sigma_i\) 都看作连续噪声过程在不同时间点的离散化后,两条路线可以用同一个随机微分方程框架统一描述。

SDE 统一视角#

  连续时间前向过程写成 Itô SDE:

\[\mathrm{d}\bx =\boldsymbol{f}(\bx,t)\mathrm{d}t +g(t)\mathrm{d}\bB_t,\]

其中 \(\bB_t\) 是与 \(\bx\) 同维的标准布朗运动,\(\boldsymbol{f}(\bx,t)\) 是漂移,\(g(t)\) 是标量扩散系数。标量扩散系数决定每个无穷小时段 \(\mathrm{d}t\) 内向样本注入随机噪声的强度:随机项 \(g(t)\mathrm{d}\bB_t\) 的方差为 \(g(t)^2\mathrm{d}t\)⁠,"标量"意味着所有维度共享同一个噪声强度,即各向同性加噪,\(g(t)\) 越大噪声注入越快、样本被破坏得越剧烈。它与前文的离散加噪参数直接对应:第 \(t\) 步单独加入的噪声方差是 \(\beta_t\)⁠,连续时间极限下单位时间注入的噪声方差正是 \(g(t)^2\)⁠,因此 DDPM 对应的方差保持 SDE 取 \(g(t)=\sqrt{\beta(t)}\)⁠,其中 \(\beta(t)\)\(\beta_t\) 的连续化。作为直观例子,若 \(\beta_t\)\(1\times10^{-4}\) 线性增长到 \(2\times10^{-2}\)⁠,则 \(g(t)=\sqrt{\beta(t)}\) 从约 0.01 缓慢增大到约 0.14,前期加噪慢、后期加噪快,配合噪声的累计效应使 \(t\) 越大样本越接近纯噪声。标准布朗运动(standard Brownian motion,也称维纳过程)是描述"纯随机游走"的连续时间随机过程:它从 \(\bB_0=\bzero\) 出发,路径连续,任意两个不相交时间段内的增量相互独立,且增量 \(\bB_t-\bB_s\) 服从均值为 0、方差为 \((t-s)\bI\) 的高斯分布。因此每个无穷小时段 \(\mathrm{d}t\) 内的增量 \(\mathrm{d}\bB_t\) 相当于方差为 \(\mathrm{d}t\) 的独立高斯扰动,路径在任何时刻都不可微,这正是 SDE 中随机项的来源;离散求解时用 \(\sqrt{\mathrm{d}t}\) 乘以标准高斯向量来模拟这一增量。方差保持(variance preserving,VP)SDE 是 DDPM 的连续极限之一;方差爆炸(variance exploding,VE)SDE 保留均值并随时间增加方差。若 \(p_t(\bx)\) 的分数已知,反向时间 SDE 可写为

\[\mathrm{d}\bx =\left[\boldsymbol{f}(\bx,t) -g(t)^2\nabla_{\bx}\log p_t(\bx)\right]\mathrm{d}t +g(t)\mathrm{d}\overline{\bB}_t,\]

其中 \(\overline{\bB}_t\) 表示 反向时间布朗运动 (reverse-time Brownian motion):它与正向方程中的 \(\bB_t\) 一样是标准布朗运动,但沿时间递减的方向演化,并且是与 \(\bB_t\) 不同的随机过程 ——横线正是用于区分二者,也提示反向噪声并不是把正向噪声的路径简单倒放。反向积分从 \(T\)\(0\) 进行,时间增量 \(\mathrm{d}t<0\)⁠,因此每一步随机项 \(g(t)\,\mathrm{d}\overline{\bB}_t\) 的方差为 \(g(t)^2|\mathrm{d}t|\)⁠。程序实现时无需对布朗运动本身做特殊处理,只需在每一步用方差为 \(|\mathrm{d}t|\) 的高斯增量独立采样,并让时间严格递减、遵循所用求解器的时间方向约定。具有相同边缘分布的概率流 ODE 为

\[\frac{\mathrm{d}\bx}{\mathrm{d}t} =\boldsymbol{f}(\bx,t) -\frac{1}{2}g(t)^2\nabla_{\bx}\log p_t(\bx).\]

它不含随机项,可使用 ODE 求解器并在一定条件下计算似然,但“相同边缘分布”不代表单个随机轨迹相同。

  下面的动画把分数向量场与反向时间过程放在同一画面中,展示样本如何沿高概率区域的方向移动,并比较带随机扰动的反向 SDE 与不含随机项的概率流 ODE。

  下面的 dsm_batch 为去噪分数匹配构造一批训练对。输入 x0 是以第一轴为批次轴的干净样本,sigma 是长度等于批量的正噪声尺度,rngNumPy 随机数生成器。函数返回两个与 x0 同形的数组:加噪样本 noisy 和条件高斯分布的目标分数 target_score

import numpy as np

def dsm_batch(x0, sigma, rng):
    x0 = np.asarray(x0, dtype=np.float64)
    sigma = np.asarray(sigma, dtype=np.float64)
    if sigma.shape != (x0.shape[0],) or np.any(sigma <= 0):
        raise ValueError("每个样本需要一个正噪声尺度")
    scale = sigma.reshape((-1,) + (1,) * (x0.ndim - 1))
    eps = rng.normal(size=x0.shape)
    noisy = x0 + scale * eps
    target_score = -eps / scale
    return noisy, target_score

  代码先将每个样本的 sigma 改成可沿其余轴广播的形状,再采样标准高斯噪声 \(\bepsilon\) 并构造 \(\tilde{\bx}=\bx_0+\sigma\bepsilon\)⁠。返回的 target_score 对应 \(-\bepsilon/\sigma\)⁠,可与分数网络在 noisy 处的输出比较来计算损失。

  这段函数只生成训练输入和目标,不包含网络前向计算、时间条件或损失的尺度加权,也不实现反向 SDE 或概率流 ODE 的数值求解。当 sigma 非常小时,目标分数的幅值会很大,实际训练中通常需要合理的噪声下限和损失加权。

求解器与核验#

  反向 SDE 与概率流 ODE 都是连续时间的方程,描述的是"瞬时"变化;要真正生成样本,必须把它们离散成有限个时间步、逐次更新状态,这一步由数值求解器(solver)完成。离散化必然引入误差:步长越大,单步误差通常越大,但步数越多,计算量也越大。因此求解器的核心问题是:在给定的计算预算下,怎样把误差控制得尽量小,同时给出可复现的结果。常见求解器大致分三类: Euler–Maruyama (反向 SDE 的一阶离散)、 预测—校正 (predictor–corrector,PC)方法,以及用于概率流 ODE 的 ODE 求解器 (如 Runge–Kutta 等)。

反向 SDE 的离散#

  记反向 SDE 为 \(\mathrm{d}\bx=\left[\boldsymbol{f}(\bx,t)-g(t)^2\bs_{\btheta}(\bx,t)\right]\mathrm{d}t+g(t)\,\mathrm{d}\overline{\bB}_t\)⁠,其中 \(\bs_{\btheta}(\bx,t)\) 是分数网络的输出,训练时把它作为 \(\nabla_{\bx}\log p_t(\bx)\) 的估计;\(\boldsymbol{f}(\bx,t)\) 是漂移,\(g(t)\) 是扩散系数,\(\overline{\bB}_t\) 是上一节介绍的反向时间布朗运动。设步长为 \(h>0\)⁠,反向每走一步时间减少 \(h\)⁠,即这一小段的时间增量为 \(\mathrm{d}t=-h\)⁠。Euler–Maruyama 方法用一步近似代替连续变化,更新为

\[\bx_{t-h} =\bx_t -\left[\boldsymbol{f}(\bx_t,t)-g(t)^2\bs_{\btheta}(\bx_t,t)\right]h +g(t)\sqrt{h}\,\bz, \qquad \bz\sim\mathcal{N}(\bzero,\bI),\]

其中 \(\bz\) 是每个维度独立的标准高斯随机数,\(\sqrt{h}\) 来自反向时间布朗运动增量的标准差 \(\sqrt{|\mathrm{d}t|}=\sqrt{h}\)⁠。这就是为什么噪声项按步长的平方根 \(\sqrt{h}\) 缩放、而确定性项按 \(h\) 缩放,详细推导见本节 综合练习⁠。若去掉随机项,只保留确定性漂移,就得到概率流 ODE 的欧拉离散

\[\bx_{t-h} =\bx_t -\left[\boldsymbol{f}(\bx_t,t)-\frac{1}{2}g(t)^2\bs_{\btheta}(\bx_t,t)\right]h.\]

  第二个更新式正是上一节 SDE 统一视角 中概率流 ODE 的数值实现:上一节指出概率流 ODE 不含随机项、可以使用 ODE 求解器,这里给出的是它的欧拉离散。因此带随机项的 Euler–Maruyama 与不带随机项的欧拉更新,正好对应上一节介绍的 反向 SDE概率流 ODE 两种动力学:后者从同一起点出发只产生一条确定轨迹,便于复现;二者在连续极限下具有相同的边缘分布,但单个轨迹不同,这正是上一节所说"相同边缘分布不代表单个随机轨迹相同"在离散层面上的体现。

  两条更新都从较噪的 \(\bx_t\) 走向较干净的 \(\bx_{t-h}\)⁠,时间严格递减。 预测—校正 (predictor–corrector,PC)方法在此基础上把一步拆成两次网络调用:先用上面的更新式"预测"一个候选状态,再在新位置重新计算分数,用一次 Langevin 型修正把它"校正"到目标分布上。以 Euler–Maruyama 为预测步为例,一步更新为

\[\begin{split}\begin{aligned} \bx' &=\bx_t -\left[\boldsymbol{f}(\bx_t,t)-g(t)^2\bs_{\btheta}(\bx_t,t)\right]h +g(t)\sqrt{h}\,\bz, &&\qquad \bz\sim\mathcal{N}(\bzero,\bI),\\ \bx_{t-h} &=\bx' +\frac{\eta}{2}\bs_{\btheta}(\bx',t-h) +\sqrt{\eta}\,\bz', &&\qquad \bz'\sim\mathcal{N}(\bzero,\bI), \end{aligned}\end{split}\]

其中第一式是预测步,与前面的 Euler–Maruyama 更新完全相同,只是把结果记为候选 \(\bx'\)⁠;第二式是校正步:在候选处重新计算分数 \(\bs_{\btheta}(\bx',t-h)\)⁠,再做一次与前面"NCSN 与退火 Langevin 动力学"一节同构的 Langevin 更新,步长为 \(\eta>0\)⁠,把候选推向目标分布 \(p_{t-h}(\bx)\) 的高密度区域。若预测步改用概率流 ODE 的欧拉离散,则第一式去掉随机项即可,校正步保持不变。校正步也可以重复若干次,每多一次就多一次网络调用,步长 \(\eta\) 常取与该步噪声水平相称的较小值。相比只走一步预测,PC 在相同步数下减小了单步误差;校正只做一次时每步调用分数网络两次,网络评估次数翻倍,重复校正则随之进一步增加。

NFE 与公平比较#

  程序设置中写的一个"步"并不一定只调用一次网络:PC 方法每步调用两次,某些高阶 ODE 求解器每步调用多次,自适应方法还会根据误差估计改变步长。因此比较求解器效率时,应报告网络评估次数(NFE),即生成一个样本实际调用分数网络的次数,而不是名义步数。NFE 直接反映最主要的计算量,也能让"步数相同但每步计算量不同"的方法公平比较。

  除了 NFE,比较时还要保证其他设置一致:时间变量的方向,反向必须严格递减;SDE 系数,\(\boldsymbol{f}(\bx,t)\)⁠、\(g(t)\)⁠、\(\bs_{\btheta}(\bx,t)\) 取自同一时刻;网络训练时的分数尺度,训练与采样使用同一套 \(t\)\(\sigma\) 约定;以及求解器接口,初始状态、随机种子、容差。每次只改变一个被比较的因素、固定其余因素,才能把结果差异归因于被比较的求解器。

核验方法#

  数值求解的正确性可以用几种低成本方式核验:① 用很小的步长,例如减半,重复运行,结果应趋于稳定,若明显变化则说明步长还不够小;② 在已知解析分数的一维高斯或高斯混合上,检查更新方向与最终样本的统计量;③ 检查每步是否出现 NaN 或发散,并监控样本范数与方差;④ 固定随机种子重复运行,确认结果可复现。单步误差如何随步长累积、以及噪声项为什么按 \(\sqrt{h}\) 缩放,见本节 综合练习⁠。

核心推导与实现核验#

核心关系

\[\nabla_{\bx_t}\log q(\bx_t\mid\bx_0)=-\frac{\tilde{\bepsilon}_t}{\sqrt{1-\bar\alpha_t}},\qquad \bs_{\btheta}(\bx_t,t)=-\frac{\bepsilon_{\btheta}(\bx_t,t)}{\sqrt{1-\bar\alpha_t}}.\]

  推导路径。 对高斯条件密度的二次型关于 \(\bx_t\) 求梯度,得到负残差除以方差;再用 \(\bx_t\) 的解析重参数化,把残差写成累计噪声 \(\tilde{\bepsilon}_t\)⁠。由此可把网络对累计噪声的预测与分数预测线性转换。

关键条件

  去噪分数匹配的等价性依赖积分和微分可交换、边界项消失等正则条件。反向 SDE 还要求前向扩散具有适当光滑密度;在离散数据上通常先连续化或加入噪声。

数据规模

  对任意一个含噪样本,分数网络输出 \(\bs_{\btheta}(\bx_t,t)\)⁠、含噪数据 \(\bx_t\) 和解析式中构造该样本的累计噪声 \(\tilde{\bepsilon}_t\) 必须具有完全相同的大小。一个批次中的每个样本只需一个时间 \(t\) 或噪声尺度 \(\sigma\)⁠,程序会把它用于该样本的全部特征;SDE 中的漂移项也必须与输入数据一样大。

常见误区

  分数是对输入 \(\bx\) 的梯度,不是对参数的梯度;负号和噪声标准差因子最容易写错。反向时间积分不能在保持正向 \(\mathrm{d}t\) 的同时照抄漂移符号。

动手检查

  对已知一维高斯分布,其真实分数为 \(-(x-\mu)/\sigma^2\)⁠;用该例检查网络目标、Langevin 更新和 SDE 离散。对解析式中的 \(\tilde{\bepsilon}_t\) 与对应时间 \(t\) 的分数转换做逐元素数值比较。

数值稳定性与规模

  小噪声时分数目标范数很大,需合理权重、参数化和梯度控制。数值求解应检查步长敏感性,并报告网络评估次数(NFE);高阶求解器不保证在错误分数场上产生正确样本。

本节小结#

  1. 分数是对数密度关于样本的梯度,可通过已知扰动核进行去噪分数匹配。

  2. NCSN 用多个噪声尺度和退火 Langevin 动力学从平滑分布逐步接近数据分布。

  3. 反向 SDE 与概率流 ODE 统一了多类扩散过程,但随机轨迹、离散求解器和成本并不相同。

综合练习#

  程序题应固定随机种子、写出维度断言并报告运行环境;比较题还应固定数据划分、随机种子集合和训练预算。全部参考答案见 分数模型与扩散 SDE 答案⁠。

  1. 高斯分数推导。\(p(\bx)=\mathcal N(\bmu,\sigma^2\bI)\)⁠,从对数密度出发推导分数 \(\nabla_{\bx}\log p(\bx)\)⁠,说明其维度和方向,并证明密度的归一化常数不会影响分数。

  2. 噪声预测与分数。\(\bx_t=\sqrt{\bar\alpha_t}\bx_0+\sqrt{1-\bar\alpha_t}\tilde{\bepsilon}_t\) 推导 \(\nabla_{\bx_t}\log q(\bx_t\mid\bx_0)=-\tilde{\bepsilon}_t/\sqrt{1-\bar\alpha_t}\)⁠,进而写出噪声预测网络与分数网络输出的转换关系。

  3. 去噪分数匹配等价性。\(p_\sigma(\tilde\bx)=\int q_\sigma(\tilde\bx\mid\bx_0)p(\bx_0)\,\mathrm{d}\bx_0\)⁠,其中 \(q_\sigma(\tilde\bx\mid\bx_0)=\mathcal{N}(\bx_0,\sigma^2\bI)\)⁠。对固定 \(\sigma\)⁠,证明去噪目标

    \[\frac{1}{2}\mathbb{E}_{\bx_0,\tilde\bx\mid\bx_0} \left[ \left\| \bs_{\btheta}(\tilde\bx,\sigma) -\nabla_{\tilde\bx}\log q_\sigma(\tilde\bx\mid\bx_0) \right\|_2^2 \right]\]

    与显式分数匹配目标

    \[\frac{1}{2}\mathbb{E}_{\tilde\bx} \left[ \left\| \bs_{\btheta}(\tilde\bx,\sigma) -\nabla_{\tilde\bx}\log p_\sigma(\tilde\bx) \right\|_2^2 \right]\]

    相差一个与 \(\btheta\) 无关的常数。提示:把第一个目标的平方展开为三项;利用分部积分证明对任意固定 \(\bx_0\)\(\mathbb{E}_{q_\sigma(\cdot\mid\bx_0)}\left[\bs_{\btheta}(\tilde\bx,\sigma)\cdot\nabla_{\tilde\bx}\log q_\sigma(\tilde\bx\mid\bx_0)\right] = -\mathbb{E}_{q_\sigma(\cdot\mid\bx_0)}\left[\nabla_{\tilde\bx}\cdot\bs_{\btheta}(\tilde\bx,\sigma)\right]\)⁠,再对 \(\bx_0\) 取平均并利用 \(p_\sigma\) 的定义,把交叉项改写为 \(-\mathbb{E}_{\tilde\bx}\left[\bs_{\btheta}(\tilde\bx,\sigma)\cdot\nabla_{\tilde\bx}\log p_\sigma(\tilde\bx)\right]\)⁠。说明推导需要什么正则条件(例如 \(p_\sigma(\tilde\bx)\bs_{\btheta}(\tilde\bx,\sigma)\)\(\lVert\tilde\bx\rVert\to\infty\) 时趋于 0)。

  4. 噪声尺度的加权。\(\tilde\bx=\bx_0+\sigma\bepsilon\)⁠,\(\bepsilon\sim\mathcal{N}(\bzero,\bI)\)\(d\) 维标准高斯噪声。对固定 \(\sigma\)⁠,计算 \(\mathbb{E}_{\bepsilon}\left[\left\|\frac{\bepsilon}{\sigma}\right\|_2^2\right]\)⁠,说明条件分数目标的期望尺度随 \(\sigma\) 如何变化;证明取 \(\lambda(\sigma)=\sigma^2\) 时,\(\mathbb{E}_{\bepsilon}\left[\lambda(\sigma)\left\|\frac{\bepsilon}{\sigma}\right\|_2^2\right]\)\(\sigma\) 无关。进一步说明:若把分数网络参数化为 \(\bs_{\btheta}(\tilde\bx,\sigma)=-\bepsilon_{\btheta}(\tilde\bx,\sigma)/\sigma\)⁠,则 \(\lambda(\sigma)=\sigma^2\) 时的去噪分数匹配目标退化为预测 \(\bepsilon\) 的均方误差,与 DDPM 简化损失形式一致。

  5. Langevin 离散计算。 对标准正态目标使用真实分数 \(s(x)=-x\)⁠,Euler 更新为 \(x_{k+1}=(1-\eta/2)x_k+\sqrt\eta z_k\)⁠。推导该离散链稳定时的平稳方差,并说明当 \(\eta\to0\) 时为什么趋近目标方差 1。

  6. 反向 SDE 与 ODE 计算。 在某一点取前向漂移 \(\boldsymbol f=\bzero\)⁠、扩散系数 \(g=2\)⁠、分数 \(\bs=-\bx\)⁠,且 \(\bx=(3,-1)\)⁠。分别计算反向 SDE 与概率流 ODE 的确定性漂移,并说明从 \(T\) 积分到 0 时还必须处理时间步的符号。

  7. 分数训练与采样实现。 实现多噪声尺度的去噪分数匹配批次构造、加权损失和退火 Langevin 采样;网络输入包含噪声尺度,程序记录每个尺度的步数和累计 NFE。

  8. 解析分数核验。 对已知一维高斯和二维高斯混合,先用解析分数检查目标、Langevin 更新及 Euler–Maruyama 实现;再逐元素验证网络的噪声预测 \(\bepsilon_{\btheta}\) 与分数预测的换算,并比较模拟样本的均值、方差或二维分布图。

  9. 测试设计。 至少测试:分数与输入同形、噪声尺度可正确广播、分数方向指向高斯均值、小噪声目标仍为有限值、反向时间网格严格递减、固定种子可复现,以及 NFE 计数等于实际网络调用次数。

  10. 噪声尺度与校正步比较。 对同一 NCSN 比较不同噪声尺度数量和每尺度 Langevin 步数。固定数据划分、随机种子集合、分数网络和训练预算;报告生成质量与覆盖、训练时间、固定样本数生成时间、NFE、参数量及训练/生成峰值内存。

  11. 反向 SDE 与概率流 ODE 比较。 使用同一个已训练分数网络和尽量相近的 NFE,比较随机反向 SDE 与确定性概率流 ODE。固定初始分布、随机种子集合、容差或步长预算;报告生成质量、多样性、训练与生成时间、NFE、参数量及峰值内存。

  12. 求解器比较。 比较 Euler–Maruyama、预测—校正方法和自适应 ODE 求解器。固定分数模型、初始样本集合、随机种子集合和最大 NFE;报告生成质量、失败率、训练共享成本、固定样本数生成时间、实际 NFE、参数量及峰值内存,并分析高阶方法每步多次调用网络的成本。

  13. Euler–Maruyama 离散推导。 设反向 SDE 为 \(\mathrm{d}\bx=\boldsymbol{f}(\bx,t)\mathrm{d}t+g(t)\,\mathrm{d}\overline{\bB}_t\)⁠,把包含分数项的漂移统一记为 \(\boldsymbol{f}(\bx,t)\)⁠;利用反向时间布朗运动增量的性质 \(\overline{\bB}_t-\overline{\bB}_{t-h}\sim\mathcal{N}(\bzero,h\bI)\)⁠,反向走一步的时间增量为 \(-h\)⁠,解释为什么确定性项按步长 \(h\) 缩放、而噪声项按 \(\sqrt{h}\) 缩放;由此写出从 \(\bx_t\)\(\bx_{t-h}\) 的 Euler–Maruyama 更新式,并说明反向时间方向(\(\mathrm{d}t<0\)⁠)对公式中各项符号的影响。

  14. 一步更新与误差估计。 对概率流 ODE 取 \(\boldsymbol{f}=\bzero\)⁠、\(g(t)=g`(常数)、分数为 :math:\)bs_{btheta}(bx,t)=-bx/sigma^2`,从 \(\bx_t\) 出发手算一步欧拉更新 \(\bx_{t-h}\)⁠;再对同一设定写出反向 SDE 的 Euler–Maruyama 更新,比较二者的确定性部分与随机部分。若步长减半,说明为什么一阶方法的单步误差大约减半,而两步累积后的整体误差仍随步长线性减小,全局误差为一阶;二阶方法,例如中点法,其误差则随步长平方减小。