2D扩散模型入门指南:从数学基础到PyTorch实战

1次阅读
没有评论

共计 1792 个字符,预计需要花费 5 分钟才能阅读完成。

image.webp

背景:为什么需要扩散模型?

在图像生成领域,我们熟悉的 GAN 和 VAE 各有优缺点:

2D 扩散模型入门指南:从数学基础到 PyTorch 实战

  • GAN:生成质量高但训练不稳定,容易模式坍塌
  • VAE:训练稳定但生成图像往往模糊

扩散模型则提供了一种新思路——通过逐步加噪和去噪的过程,既保持了生成质量,又让训练过程更加可控。就像画家先打草稿再逐步细化,扩散模型通过多个时间步的迭代达到理想效果。

数学原理:扩散过程解析

扩散模型的核心是 前向过程 反向过程

  1. 前向过程(加噪)
    定义为一个马尔可夫链,逐步向数据添加高斯噪声:
    $$q(\mathbf{x}t|\mathbf{x}}) = \mathcal{N}(\mathbf{xt; \sqrt{1-\beta_t}\mathbf{x})$$
    其中 $\beta_t$ 是噪声调度参数}, \beta_t\mathbf{I

  2. 噪声调度策略
    通常采用线性或余弦调度,控制噪声增加的节奏。余弦调度效果更好:
    $$\beta_t = \text{clip}(1-\frac{\alpha_t}{\alpha_{t-1}}, 0.999)$$
    $$\alpha_t = \frac{\cos(t/T+s}{1+s}\pi/2)^2$$

PyTorch 实现关键组件

1. 高斯噪声生成模块

import torch
def gaussian_noise(x, t, betas):
    """为输入 x 在时间步 t 添加噪声"""
    sqrt_alpha = torch.sqrt(1 - betas[t])
    noise = torch.randn_like(x)
    return sqrt_alpha * x + (1 - sqrt_alpha) * noise

2. 时间步嵌入层

class TimeEmbedding(nn.Module):
    def __init__(self, dim):
        super().__init__()
        self.dim = dim
        # 使用正弦位置编码
        half_dim = dim // 2
        emb = math.log(10000) / (half_dim - 1)
        emb = torch.exp(torch.arange(half_dim) * -emb)
        self.register_buffer('emb', emb)

    def forward(self, t):
        emb = t[:, None] * self.emb[None, :]
        return torch.cat([emb.sin(), emb.cos()], dim=-1)

3. 简易 UNet 架构

class UNet(nn.Module):
    def __init__(self):
        super().__init__()
        # 下采样路径
        self.down1 = nn.Sequential(nn.Conv2d(3, 64, 3, padding=1),
            nn.GroupNorm(8, 64),
            nn.SiLU())
        # 上采样路径(包含 skip connection)self.up1 = nn.Sequential(nn.Conv2d(128, 64, 3, padding=1),
            nn.GroupNorm(8, 64),
            nn.SiLU())
        # ... 其他层定义

    def forward(self, x, t):
        # 时间嵌入
        t_emb = self.time_mlp(t)
        # 下采样
        h1 = self.down1(x)
        # ... 中间层
        # 上采样 +skip connection
        h = self.up1(torch.cat([h, h_skip], dim=1))
        return h

训练实践要点

数据预处理

  • 图像必须归一化到 [-1, 1] 范围
  • 建议使用 RandomHorizontalFlip 等基础增强

超参数设置

  1. 学习率:从 3e- 5 开始尝试
  2. batch size:根据显存选择最大可能值
  3. 梯度裁剪:设置 clip_norm=1.0 防止梯度爆炸

常见问题排查

Loss 不收敛的可能原因

  • 噪声调度设置不合理(尝试调整 $\beta$ 范围)
  • 时间步嵌入未正确接入 UNet
  • 学习率过高 / 过低

显存优化技巧

  1. 使用混合精度训练
  2. 减小 batch size
  3. 使用梯度检查点技术

进阶方向

高分辨率生成

  • 使用 Latent Diffusion(在潜在空间操作)
  • 分块训练策略

条件生成

  • 在 UNet 中加入条件信息(如类别标签)
  • 使用 Classifier Guidance 技术

结语

通过这篇指南,我们实现了扩散模型从理论到实践的完整闭环。虽然扩散模型计算成本较高,但它的稳定性和生成质量使其成为当前最值得关注的生成模型之一。建议读者从 MNIST 等小数据集开始实验,逐步掌握调参技巧。

正文完
 0
评论(没有评论)