手把手推导:从Score Function到Langevin采样,彻底搞懂SGM扩散模型的数学原理
手把手推导:从Score Function到Langevin采样,彻底搞懂SGM扩散模型的数学原理
在生成模型领域,Score-Based Generative Modeling(SGM)正以其独特的数学美感和理论深度吸引着越来越多的研究者。与常见的生成对抗网络(GAN)或变分自编码器(VAE)不同,SGM通过直接建模概率密度的梯度场(即Score Function)来实现数据生成,这一思路不仅优雅,而且在实践中展现出了惊人的效果。本文将带您深入SGM的核心数学原理,从Score Function的定义出发,逐步推导到Langevin采样算法的实现细节,让您真正理解这一强大模型背后的理论基础。
1. Score Function:概率密度的导航图
1.1 Stein Score Function的定义与几何意义
在概率论中,给定一个概率密度函数p(x),其Stein Score Function定义为:
s(x) = \nabla_x \log p(x)这个看似简单的定义蕴含着深刻的几何意义。Score Function实际上描述了概率密度函数在x点处的"最陡上升方向"。想象你站在一个概率密度构成的山丘上,Score Function就是告诉你应该朝哪个方向走才能最快到达山顶(即概率密度最大的区域)。
对于高斯分布N(μ, σ²I),我们可以具体计算出其Score Function:
\begin{aligned} p(x) &= \frac{1}{(2\pi)^{d/2}\sigma^d}\exp\left(-\frac{\|x-\mu\|^2}{2\sigma^2}\right) \\ \log p(x) &= -\frac{\|x-\mu\|^2}{2\sigma^2} + C \\ s(x) &= \nabla_x \log p(x) = -\frac{x-\mu}{\sigma^2} \end{aligned}这个结果清晰地展示了Score Function的方向性:它总是指向分布的中心(均值μ),且随着距离中心越远,其强度越大。
1.2 加噪过程中的Score Function变化
在SGM中,我们通过逐步加噪的过程来构造一系列分布。设原始数据分布为q(x₀),在加噪步骤t时,数据分布变为:
q(x_t|x_0) = \mathcal{N}(x_0, \sigma_t^2 I)对应的边缘分布为:
q(x_t) = \int q(x_t|x_0)q(x_0)dx_0根据1.1节的推导,条件分布的Score Function为:
\nabla_{x_t} \log q(x_t|x_0) = -\frac{x_t - x_0}{\sigma_t^2}然而,我们真正需要的是边缘分布的Score Function:
s_t(x_t) = \nabla_{x_t} \log q(x_t)这个无法直接计算,因为q(x_t)的表达式涉及积分。这正是我们需要神经网络来近似Score Function的原因。
2. Score Matching:训练Score Network
2.1 目标函数的推导
我们的目标是训练一个网络sθ(xₜ,t)来近似真实的Score Function sₜ(xₜ)。直接的想法是最小化以下L₂损失:
\mathcal{L} = \mathbb{E}_{q(x_t)} \left[ \| s_\theta(x_t,t) - \nabla_{x_t} \log q(x_t) \|^2 \right]但这个目标不可行,因为我们无法直接计算∇ₓlog q(xₜ)。幸运的是,我们可以利用Score Matching的技巧,通过以下等价形式来避免直接计算:
\mathcal{L} = \mathbb{E}_{q(x_t|x_0)q(x_0)} \left[ \| s_\theta(x_t,t) - \nabla_{x_t} \log q(x_t|x_0) \|^2 \right] + C其中C是与θ无关的常数。根据1.2节的结果,我们可以将目标函数具体化为:
\mathcal{L} = \mathbb{E} \left[ \left\| s_\theta(x_t,t) + \frac{x_t - x_0}{\sigma_t^2} \right\|^2 \right]2.2 与DDPM的联系
有趣的是,SGM的目标函数可以与DDPM(Denoising Diffusion Probabilistic Models)建立联系。考虑加权损失:
\mathcal{L}^* = \sigma_t^4 \mathcal{L} = \mathbb{E} \left[ \left\| \frac{x_t - x_0}{\sigma_t} + \sigma_t s_\theta(x_t,t) \right\|^2 \right]令z = (xₜ - x₀)/σₜ(这是标准正态噪声),zθ = -σₜsθ(xₜ,t),则损失变为:
\mathcal{L}^* = \mathbb{E} \left[ \| z - z_\theta \|^2 \right]这正是DDPM中预测噪声的目标函数!这一发现揭示了两种看似不同的生成模型背后深刻的统一性。
3. Langevin动力学与采样过程
3.1 Langevin动力学的基本原理
Langevin动力学提供了一种通过Score Function进行采样的方法。其离散形式为:
x_{i+1} = x_i + \epsilon \nabla_x \log p(x_i) + \sqrt{2\epsilon} z_i其中zᵢ ∼ N(0,I),ϵ是步长。这一更新公式可以理解为:
- 漂移项:ϵ∇ₓlog p(xᵢ)推动样本向高概率区域移动
- 扩散项:√(2ϵ)zᵢ保证探索性,避免陷入局部极值
在适当条件下,当ϵ→0且迭代次数→∞时,xᵢ的分布会收敛到p(x)。
3.2 SGM中的退火Langevin采样
在SGM中,我们采用退火(annealing)策略,从高噪声级别逐步过渡到低噪声级别。具体算法如下:
- 初始化xₜ⁰ ∼ N(0,I),t=T
- 对每个t,执行N步Langevin更新:
x_t^{i+1} = x_t^i + \frac{\alpha_t}{2} s_\theta(x_t^i,t) + \sqrt{\alpha_t} z_i - 将最终样本作为下一噪声级别的初始值:xₜ₋₁⁰ = xₜᴺ
- t = t-1,重复步骤2-3直到t=0
其中αₜ是噪声级别相关的步长。这种退火策略有效地克服了传统Langevin采样在多模态分布中的混合问题。
4. 实践中的技巧与优化
4.1 噪声调度与步长选择
在实践中,噪声级别{σₜ}的选择至关重要。常见的策略包括:
| 调度类型 | 公式 | 特点 |
|---|---|---|
| 线性调度 | σₜ = σₘₐₓ - (σₘₐₓ-σₘᵢₙ)(t/T) | 简单直接 |
| 指数调度 | σₜ = σₘₐₓ(σₘᵢₙ/σₘₐₓ)^(t/T) | 更关注低噪声区域 |
| 余弦调度 | σₜ = cos(πt/2T) | 平滑过渡 |
步长αₜ通常与σₜ²成正比,以确保不同噪声级别的更新幅度相对一致。
4.2 网络架构设计
Score Network sθ(xₜ,t)通常采用类似UNet的结构,但有以下特殊考虑:
- 时间嵌入:将噪声级别t通过正弦位置编码嵌入网络
- 噪声条件:在残差块中加入与σₜ相关的缩放因子
- 归一化:使用Group Normalization而非Batch Normalization
一个典型的实现片段可能如下:
class ScoreNetwork(nn.Module): def __init__(self): super().__init__() self.time_embed = nn.Sequential( nn.Linear(1, 128), nn.SiLU(), nn.Linear(128, 256) ) self.conv1 = nn.Conv2d(3, 64, 3, padding=1) self.downblocks = nn.ModuleList([DownBlock(64*(2**i)) for i in range(4)]) self.upblocks = nn.ModuleList([UpBlock(64*(2**(3-i))) for i in range(4)]) def forward(self, x, t): t_emb = self.time_embed(t.view(-1,1)) h = self.conv1(x) skips = [] for block in self.downblocks: h = block(h, t_emb) skips.append(h) for i, block in enumerate(self.upblocks): h = block(h, skips[-(i+1)], t_emb) return h4.3 采样加速技巧
为了提高采样效率,可以应用以下技巧:
- 子序列采样:不必遍历所有T个噪声级别,而是选择子序列{t₁,...,tₖ}
- 预测校正:交替使用Langevin步骤和Score Matching校正
- 高阶方法:使用二阶或更高阶的数值积分方法
在实践中,通常需要在生成质量和计算效率之间进行权衡。例如,使用50-100个噪声级别配合100-200步Langevin更新,可以在合理时间内获得高质量样本。
