扩散模型(Diffusion Model)原理与图像生成实战
1.1 本章学习目标与重点
💡 学习目标:掌握扩散模型的核心原理、前向扩散与反向扩散过程,以及基于扩散模型的图像生成任务实战流程。 💡 学习重点:理解扩散模型的噪声添加与噪声消除机制,学会使用 PyTorch 搭建 DDPM 模型,完成手写数字图像生成任务。
1.2 扩散模型的核心思想
1.2.1 为什么需要扩散模型
💡 传统的生成模型(如 GAN)存在训练不稳定、模式崩溃等问题。扩散模型作为一种基于概率的生成模型,通过逐步添加噪声和逐步去除噪声的双向过程,实现了更稳定的训练和更高质量的生成效果。 扩散模型的灵感来源于非平衡热力学,它的核心是将复杂的生成问题拆解为多个简单的马尔可夫链步骤。在图像生成、文本生成、语音合成等领域,扩散模型的表现已经超越了传统生成模型。
1.2.2 扩散模型的基本框架
💡 扩散模型包含两个核心过程:前向扩散过程和反向扩散过程。
- 前向扩散过程:从真实数据出发,逐步向数据中添加高斯噪声。经过 T 步后,数据会变成完全随机的噪声。
- 反向扩散过程:从随机噪声出发,训练一个神经网络逐步去除噪声。经过 T 步后,噪声会还原为真实的数据分布。
整个过程遵循马尔可夫链的假设,即每一步的状态只与前一步有关。
1.3 前向扩散过程详解
💡 前向扩散过程是一个固定的、非训练的过程。它的目标是通过逐步添加噪声,将真实图像 $x_0$ 转换为随机噪声 $x_T$。
1.3.1 前向扩散的数学原理
前向扩散过程的每一步,都会按照以下公式向图像中添加噪声: $x_t = \sqrt{\alpha_t} x_{t-1} + \sqrt{1 - \alpha_t} \epsilon_t$ 其中:
- $x_t$ 表示第 t 步添加噪声后的图像
- $\alpha_t$ 是一个预先设定的噪声系数,满足 $0 < \alpha_t < 1$
- $\epsilon_t$ 是服从标准正态分布的高斯噪声
为了计算方便,通常会定义累计乘积系数: $\bar{\alpha}t = \prod{i=1}^t \alpha_i$ 通过累计系数,可以直接从 $x_0$ 计算出任意步的 $x_t$: $x_t = \sqrt{\bar{\alpha}_t} x_0 + \sqrt{1 - \bar{\alpha}_t} \epsilon$
⚠️ 注意:前向扩散的步数 T 是一个超参数。T 越大,前向扩散越充分,反向扩散的效果越好,但训练和生成的时间也会越长。
1.3.2 前向扩散过程的代码实现
import torch
import numpy as np
import matplotlib.pyplot as plt
# 定义扩散过程的超参数
T = 1000 # 扩散步数
beta_start = 0.0001 # 初始噪声系数
beta_end = 0.02 # 最终噪声系数
# 生成线性变化的 beta 序列
beta = torch.linspace(beta_start, beta_end, T)
alpha = 1 - beta
alpha_bar = torch.cumprod(alpha, dim=)
():
eps = torch.randn_like(x0).to(device)
alpha_bar_t = alpha_bar[t].reshape(-, , , ).to(device)
xt = torch.sqrt(alpha_bar_t) * x0 + torch.sqrt( - alpha_bar_t) * eps
xt, eps
torchvision.datasets MNIST
torchvision.transforms ToTensor
dataset = MNIST(root=, train=, download=, transform=ToTensor())
x0, _ = dataset[]
x0 = x0.unsqueeze()
device = torch.device( torch.cuda.is_available() )
plt.figure(figsize=(, ))
i, t ([, , , , , ]):
xt, _ = forward_diffusion(x0, torch.tensor([t]), device)
xt = xt.squeeze().cpu().detach().numpy()
plt.subplot(, , i + )
plt.imshow(xt, cmap=)
plt.title()
plt.axis()
plt.show()


