扩散模型(Diffusion Model)原理与图像生成实战

学习目标
掌握扩散模型的核心原理、前向扩散与反向扩散过程,以及基于扩散模型的图像生成任务实战流程。重点理解噪声添加与消除机制,学会使用 PyTorch 搭建 DDPM 模型,完成手写数字图像生成。
核心思想
传统的生成模型(如 GAN)常面临训练不稳定和模式崩溃的问题。扩散模型通过逐步添加噪声和逐步去除噪声的双向过程,实现了更稳定的训练和高质量的生成效果。其灵感来源于非平衡热力学,核心是将复杂的生成问题拆解为多个简单的马尔可夫链步骤。
扩散模型包含两个核心过程:
- 前向扩散过程:从真实数据出发,逐步添加高斯噪声。经过 T 步后,数据变成完全随机的噪声。
- 反向扩散过程:从随机噪声出发,训练神经网络逐步去除噪声,还原为真实的数据分布。
整个过程遵循马尔可夫链假设,即每一步的状态只与前一步有关。
前向扩散过程详解
前向扩散是一个固定的、非训练的过程。目标是通过逐步添加噪声,将真实图像 x₀ 转换为随机噪声 x_T。
数学原理
每一步按照以下公式添加噪声:
x_t = √α_t * x_{t-1} + √(1 - α_t) * ε_t
其中 x_t 是第 t 步添加噪声后的图像,α_t 是预设的噪声系数,ε_t 是标准正态分布的高斯噪声。
为了计算方便,定义累计乘积系数:
ᾱ_t = Π_{i=1}^t α_i
通过累计系数,可以直接从 x₀ 计算出任意步的 x_t:
x_t = √ᾱ_t * x₀ + √(1 - ᾱ_t) * ε
⚠️ 注意:前向扩散的步数 T 是超参数。T 越大,前向扩散越充分,但训练和生成的时间也会越长。
代码实现
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=0) # 累计乘积
# 前向扩散函数:从 x0 生成 xt
def forward_diffusion(x0, t, device):
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()


