第5章:分数生成模型(Score-Based Generative Models)
5.1 噪音条件分数网络(Noise-Conditional Score Network)
核心概念
噪音条件分数网络(Noise-Conditional Score Network, NCSN)是分数生成模型的核心组件,其目标是学习数据分布的梯度场(即分数函数)。与传统生成模型不同,NCSN通过直接建模分数函数(对数概率密度的梯度)来实现数据生成。
数学定义
给定数据分布 ( p_{data}(x) ),分数函数定义为: [ \nabla_x \log p_{data}(x) ] NCSN通过神经网络 ( s_\theta(x, \sigma) ) 近似该分数函数,其中 ( \sigma ) 是噪声尺度参数。
网络结构与训练
1. 多尺度噪声设计
- 使用一组逐渐衰减的噪声尺度 ( { \sigma_i }_{i=1}^L )(例如 ( \sigma_1 > \sigma_2 > \dots > \sigma_L ))。
- 每个尺度对应一个扰动后的数据分布 ( p_{\sigma_i}(x) = \int p_{data}(y) \mathcal{N}(x|y, \sigma_i^2 I) dy )。
2. 损失函数
采用加权分数匹配损失(Weighted Denoising Score Matching): [ \mathcal{L}(\theta) = \frac{1}{L} \sum_{i=1}^L \lambda(\sigma_i) \mathbb{E}{x \sim p{data}} \mathbb{E}{\tilde{x} \sim \mathcal{N}(x, \sigma_i^2 I)} \left[ | s\theta(\tilde{x}, \sigma_i) + \frac{\tilde{x} - x}{\sigma_i^2} |_2^2 \right] ] 其中 ( \lambda(\sigma_i) ) 是尺度相关的权重(通常设为 ( \sigma_i^2 ))。
3. 网络架构
- 输入:带噪声的数据 ( \tilde{x} ) 和噪声尺度 ( \sigma_i )(通过嵌入或条件层注入)。
- 典型实现:U-Net 或 ResNet,配备自适应归一化层(如GroupNorm + 噪声尺度条件)。
关键特性
噪声尺度条件化
网络通过显式输入噪声尺度 ( \sigma_i ),实现对不同噪声水平下分数函数的统一建模。鲁棒性增强
多尺度噪声训练使模型能够处理低密度区域(如生成图像的边缘或罕见模式)。与SDE的关联
NCSN可视为离散化随机微分方程(SDE)的分数估计器,为连续时间扩散模型奠定基础。
代码示例(PyTorch伪代码)
class NoiseConditionalScoreNetwork(nn.Module):
def __init__(self):
super().__init__()
# 噪声尺度嵌入层
self.sigma_embed = nn.Sequential(
nn.Linear(1, 128),
nn.SiLU(),
nn.Linear(128, 256)
)
# 主干网络(简化版U-Net)
self.conv1 = nn.Conv2d(3, 64, 3, padding=1)
self.downsample = nn.MaxPool2d(2)
self.res_blocks = nn.ModuleList([ResBlock(64) for _ in range(3)])
# 输出分数(与输入同维度)
self.score_head = nn.Conv2d(64, 3, 3, padding=1)
def forward(self, x, sigma):
# 嵌入噪声尺度并注入网络
sigma_embed = self.sigma_embed(sigma.view(-1, 1))
h = self.conv1(x) + sigma_embed.unsqueeze(-1).unsqueeze(-1)
h = self.downsample(h)
for block in self.res_blocks:
h = block(h, sigma_embed)
return self.score_head(h)
# 训练损失计算
def score_matching_loss(model, x_batch, sigma_list):
losses = []
for sigma in sigma_list:
noise = torch.randn_like(x_batch) * sigma
perturbed_x = x_batch + noise
pred_score = model(perturbed_x, sigma)
target_score = -noise / (sigma ** 2)
loss = torch.mean((pred_score - target_score) ** 2)
losses.append(loss)
return sum(losses) / len(losses)
示意图

图:NCSN的多尺度噪声训练流程。噪声数据通过共享权重的网络,损失函数强制网络预测不同尺度下的分数。
案例研究:图像生成
CIFAR-10实验结果
- 使用5个噪声尺度 ( \sigma \in [0.01, 0.1, 0.5, 1.0, 5.0] )。
- 生成的图像FID分数可达15.3(优于同期GANs),验证了分数建模的有效性。
挑战与解决方案
| 问题 | 解决方法 |
|---|---|
| 高维数据分数估计不稳定 | 使用Lipschitz约束或梯度裁剪 |
| 小尺度噪声训练困难 | 渐进式噪声衰减策略 |
| 采样速度慢 | 结合DDIM或SDE求解器加速 |
