扩散模型原理与图像生成实战
核心思想与背景
传统的生成模型(如 GAN)常面临训练不稳定、模式崩溃等挑战。扩散模型作为一种基于概率的生成方法,通过逐步添加噪声和逐步去除噪声的双向过程,实现了更稳定的训练和高质量的生成效果。它的灵感来源于非平衡热力学,核心在于将复杂的生成问题拆解为多个简单的马尔可夫链步骤。
扩散模型包含两个核心过程:
- 前向扩散过程:从真实数据出发,逐步添加高斯噪声,直到数据变成完全随机的噪声。
- 反向扩散过程:训练神经网络从随机噪声出发,逐步去除噪声,还原出真实的数据分布。
整个过程遵循马尔可夫链假设,即每一步的状态只与前一步有关。理解这一机制是掌握扩散模型的关键。
前向扩散过程详解
前向扩散是一个固定的、非训练的过程。目标是通过逐步添加噪声,将真实图像 $x_0$ 转换为随机噪声 $x_T$。
数学原理
每一步按照以下公式添加噪声: $$x_t = \sqrt{\alpha_t} x_{t-1} + \sqrt{1 - \alpha_t} \epsilon_t$$ 其中 $\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$ 越大,前向扩散越充分,但训练和生成的时间也会越长。
代码实现
下面展示了如何定义扩散过程的超参数并实现前向扩散函数。这里以 PyTorch 为例,加载 MNIST 数据集进行可视化测试。
import torch
import numpy as np
import matplotlib.pyplot as plt
from torchvision.datasets import MNIST
from torchvision.transforms import ToTensor
# 定义扩散过程的超参数
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):
"""
x0: 原始图像 (batch_size, channels, height, width)
t: 扩散步数 (batch_size,)
"""
eps = torch.randn_like(x0).to(device)
alpha_bar_t = alpha_bar[t].reshape(-1, , , ).to(device)
xt = torch.sqrt(alpha_bar_t) * x0 + torch.sqrt( - alpha_bar_t) * eps
xt, eps
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()


