📖目录
- [1. 前言:为什么需要DDPM?](#1. 前言:为什么需要DDPM?)
- [2. 大白话解释:DDPM的"修复"过程](#2. 大白话解释:DDPM的"修复"过程)
- [3. 核心数学原理](#3. 核心数学原理)
-
- [3.1 扩散过程(前向过程)](#3.1 扩散过程(前向过程))
- [3.2 去噪过程(反向过程)](#3.2 去噪过程(反向过程))
- [4. DDPM算法流程详解](#4. DDPM算法流程详解)
- [5. 代码实现(带详细注释)](#5. 代码实现(带详细注释))
- [6. 网络架构图](#6. 网络架构图)
-
- [6.1 DDPM网络架构表格展示](#6.1 DDPM网络架构表格展示)
- [6.2 架构说明(大白话版)](#6.2 架构说明(大白话版))
- [6.3 网络参数说明](#6.3 网络参数说明)
- [6.4 优化建议](#6.4 优化建议)
- [7. 生成模型对比分析](#7. 生成模型对比分析)
- [8. DDPM的领域应用](#8. DDPM的领域应用)
-
- [8.1 图像生成(Stable Diffusion)](#8.1 图像生成(Stable Diffusion))
- [8.2 视频生成(Stable Video Diffusion)](#8.2 视频生成(Stable Video Diffusion))
- [8.3 分子设计(Diffusion for Chemistry)](#8.3 分子设计(Diffusion for Chemistry))
- [9. DDPM的优劣势分析](#9. DDPM的优劣势分析)
- [10. 未来展望](#10. 未来展望)
- [11. 结语](#11. 结语)
1. 前言:为什么需要DDPM?
在生成式AI领域,传统GAN(生成对抗网络)就像一个"画匠",试图直接画出逼真的图像,但往往容易"画歪"(模式崩溃)。而DDPM(Denoising Diffusion Probabilistic Models)则像一个"修复师",通过逐步去噪的方式,将随机噪声变成清晰图像。就像你把一张完美的照片慢慢划伤,再训练一个"修复师"把它恢复原状。
"GAN是直接画图,DDPM是慢慢修复图。"------这就是DDPM的核心思想。
2. 大白话解释:DDPM的"修复"过程
想象你有一张完美的照片(比如猫的图片),但不小心在上面划了道痕(噪声):
- 第一步:你慢慢加更多划痕,直到照片变成一团乱糟糟的噪声(扩散过程)
- 第二步:你训练一个"修复师"(神经网络),让他学会从噪声中恢复原图(去噪过程)
这就像:
- 你把一张崭新的手机屏幕慢慢划伤,直到看不清内容
- 然后你训练一个APP,能自动修复屏幕划痕,恢复原图
关键区别:DDPM不是直接生成图像,而是通过"去噪"过程,逐步从噪声中重建图像。
3. 核心数学原理
3.1 扩散过程(前向过程)
我们定义一个扩散过程,逐步向数据添加噪声:
q ( x t ∣ x t − 1 ) = N ( x t ; 1 − β t x t − 1 , β t I ) q(x_t|x_{t-1}) = \mathcal{N}(x_t; \sqrt{1-\beta_t}x_{t-1}, \beta_t\mathbf{I}) q(xt∣xt−1)=N(xt;1−βt xt−1,βtI)
其中:
- x t x_t xt:第t步的噪声图像
- β t \beta_t βt:第t步的噪声方差
- N \mathcal{N} N:正态分布
大白话:这就像你把一张照片慢慢加噪,每一步都加一点点随机噪声。
推导:通过递推,我们可以得到任意时间步的噪声图像:
q ( x t ∣ x 0 ) = N ( x t ; α ˉ t x 0 , ( 1 − α ˉ t ) I ) q(x_t|x_0) = \mathcal{N}(x_t; \sqrt{\bar{\alpha}_t}x_0, (1-\bar{\alpha}_t)\mathbf{I}) q(xt∣x0)=N(xt;αˉt x0,(1−αˉt)I)
其中 α ˉ t = ∏ i = 1 t ( 1 − β i ) \bar{\alpha}t = \prod{i=1}^t(1-\beta_i) αˉt=∏i=1t(1−βi)
大白话 :我们不需要一步步加噪,可以直接从原始图像 x 0 x_0 x0 生成任意时间步的噪声图像 x t x_t xt。
3.2 去噪过程(反向过程)
训练一个神经网络 ϵ θ ( x t , t ) \epsilon_\theta(x_t, t) ϵθ(xt,t) 来预测噪声:
ϵ θ ( x t , t ) ≈ ϵ \epsilon_\theta(x_t, t) \approx \epsilon ϵθ(xt,t)≈ϵ
大白话:这个神经网络的任务是"从噪声图像中预测出添加的噪声"。
优化目标:最小化预测噪声与实际噪声的均方误差:
L = E t , x 0 , ϵ [ ∥ ϵ − ϵ θ ( x t , t ) ∥ 2 ] \mathcal{L} = \mathbb{E}{t, x_0, \epsilon}[\|\epsilon - \epsilon\theta(x_t, t)\|^2] L=Et,x0,ϵ[∥ϵ−ϵθ(xt,t)∥2]
推导:通过重参数化技巧,我们可以将损失函数写为:
L = E t , x 0 , ϵ [ ∥ ϵ − ϵ θ ( α ˉ t x 0 + 1 − α ˉ t ϵ , t ) ∥ 2 ] \mathcal{L} = \mathbb{E}{t, x_0, \epsilon}[\|\epsilon - \epsilon\theta(\sqrt{\bar{\alpha}_t}x_0 + \sqrt{1-\bar{\alpha}_t}\epsilon, t)\|^2] L=Et,x0,ϵ[∥ϵ−ϵθ(αˉt x0+1−αˉt ϵ,t)∥2]
大白话 :我们不需要知道原始图像 x 0 x_0 x0,只需要知道噪声图像 x t x_t xt 和时间步 t t t,就能预测出添加的噪声 ϵ \epsilon ϵ。
4. DDPM算法流程详解
原始图像 x0 添加噪声 逐步加噪 得到噪声图像 xt 训练去噪网络 预测噪声 从噪声恢复图像 生成新图像
- 前向扩散 :从原始图像 x 0 x_0 x0 逐步添加噪声,得到 x T x_T xT
- 训练 :训练神经网络 ϵ θ \epsilon_\theta ϵθ 预测添加的噪声
- 反向去噪 :从随机噪声 x T x_T xT 开始,逐步预测并去除噪声,得到 x 0 x_0 x0
5. 代码实现(带详细注释)
python
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt
# 1. 定义扩散过程的超参数
T = 1000 # 总扩散步数
beta = torch.linspace(0.0001, 0.02, T) # 噪声方差序列
alpha = 1 - beta # 每一步保留的图像比例
alpha_bar = torch.cumprod(alpha, dim=0) # 累积乘积,用于直接计算任意时间步的噪声
# 2. 扩散过程:将原始图像x0添加噪声,得到xt
def forward_diffusion(x0, t):
"""
将图像x0添加噪声,得到xt
:param x0: 原始图像 [batch_size, channels, height, width]
:param t: 时间步 [batch_size]
:return: 添加噪声后的图像xt
"""
# 从x0生成xt,使用公式 q(xt|x0) = N(sqrt(alpha_bar_t)x0, (1-alpha_bar_t)I)
noise = torch.randn_like(x0) # 生成随机噪声
x_t = torch.sqrt(alpha_bar[t])[:, None, None, None] * x0 + torch.sqrt(1 - alpha_bar[t])[:, None, None, None] * noise
return x_t
# 3. 训练目标:预测添加的噪声
class DenoiseNet(nn.Module):
def __init__(self, input_channels=3, output_channels=3):
super(DenoiseNet, self).__init__()
# 一个简单的CNN,用于预测噪声
self.model = nn.Sequential(
nn.Conv2d(input_channels + 1, 64, kernel_size=3, padding=1), # 输入:图像+时间步
nn.ReLU(),
nn.Conv2d(64, 64, kernel_size=3, padding=1),
nn.ReLU(),
nn.Conv2d(64, output_channels, kernel_size=3, padding=1)
)
def forward(self, x, t):
"""
:param x: 当前时间步的图像 [batch_size, channels, height, width]
:param t: 时间步 [batch_size]
:return: 预测的噪声 [batch_size, channels, height, width]
"""
# 将时间步转换为嵌入向量
t_emb = torch.sin(t.float() * 10)[:, None] # 简单的时间嵌入
t_emb = t_emb.repeat(1, x.size(1)) # 扩展到与图像通道数相同
# 将时间嵌入与图像拼接
x_t = torch.cat([x, t_emb[:, :, None, None]], dim=1)
# 通过神经网络预测噪声
return self.model(x_t)
# 4. 训练循环
def train_denoise_net(model, dataloader, epochs=10):
optimizer = optim.Adam(model.parameters(), lr=1e-3)
for epoch in range(epochs):
total_loss = 0
for batch_idx, (x0, _) in enumerate(dataloader):
# 随机选择时间步
t = torch.randint(0, T, (x0.size(0),), device=x0.device)
# 从x0添加噪声得到xt
xt = forward_diffusion(x0, t)
# 预测噪声
pred_noise = model(xt, t)
# 计算损失(预测噪声与实际噪声的均方误差)
loss = nn.MSELoss()(pred_noise, torch.randn_like(xt))
# 反向传播
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_loss += loss.item()
print(f"Epoch [{epoch+1}/{epochs}], Loss: {total_loss/len(dataloader):.4f}")
return model
# 5. 生成新图像
def sample(model, num_samples=1, img_size=(3, 32, 32)):
"""
从随机噪声生成新图像
:param model: 训练好的去噪网络
:param num_samples: 生成图像数量
:param img_size: 图像尺寸
:return: 生成的图像 [num_samples, channels, height, width]
"""
# 从随机噪声开始
x = torch.randn(num_samples, *img_size)
# 从T步开始,逐步去噪
for t in reversed(range(T)):
# 将当前图像和时间步输入网络
noise_pred = model(x, torch.tensor(t, device=x.device).repeat(num_samples))
# 计算去噪后的图像
x = (x - torch.sqrt(1 - alpha[t]) * noise_pred) / torch.sqrt(alpha[t])
# 添加随机噪声(如果t>0)
if t > 0:
x += torch.sqrt(beta[t]) * torch.randn_like(x)
return x
# 6. 实际使用示例(假设已训练模型)
# model = train_denoise_net(DenoiseNet(), dataloader)
# generated_image = sample(model)
6. 网络架构图
6.1 DDPM网络架构表格展示
| 模块名称 | 输入 | 处理步骤 | 输出 | 功能说明 |
|---|---|---|---|---|
| 输入层 | x_t \\in \\mathbb{R}\^{C\\times H\\times W} 时间步 t \\in \\mathbb{N} | - 接收当前时间步的噪声图像 - 接收时间步整数 t | 噪声图像张量 x_t 时间步 t | 提供去噪过程的基础输入 |
| 时间嵌入 | 时间步 t | - 通过正弦函数生成1D嵌入: t_{\\text{emb}} = \\sin(t \\times 10) - 扩展维度与图像通道对齐 | 时间嵌入向量 t_{\\text{emb}} \\in \\mathbb{R}\^{C\\times H\\times W} | 将离散时间步转换为连续向量表示 |
| 特征拼接 | x_t \< b r \> \ \ t_{\\text{emb}} |
- 在通道维度拼接: x_{\\text{in}} = \[x_t, t_{\\text{emb}}\] | 扩展输入张量 x_{\\text{in}} \\in \\mathbb{R}\^{(C+1)\\times H\\times W} | 融合图像特征与时间信息 |
| CNN去噪网络 | x_{\\text{in}} | - 3层卷积网络结构: ① Conv2d(64) + ReLU ② Conv2d(64) + ReLU ③ Conv2d(3) + Linear | 噪声预测 \\epsilon_{\\theta}(x_t, t) \\in \\mathbb{R}\^{3\\times H\\times W} | 预测当前时间步的噪声分量 |
| 输出层 | 噪声预测 \\epsilon_{\\theta} | - 通过反向过程公式计算: x_{t-1} = \\frac{x_t - \\sqrt{1-\\alpha_t}\\epsilon_{\\theta}}{\\sqrt{\\alpha_t}} + \\sqrt{\\beta_t} \\cdot \\mathcal{N}(0, I) | 重建图像 x_{t-1} | 完成一步去噪操作 |
6.2 架构说明(大白话版)
| 模块 | 类比说明 | 技术细节 |
|---|---|---|
| 输入层 | 就像快递员拿着"破损包裹"和"破损程度说明" | 接收带噪声的图像和当前时间步 |
| 时间嵌入 | 把"破损程度说明"翻译成机器能理解的语言 | 用正弦函数生成时间特征 |
| 特征拼接 | 把"破损包裹"和"破损说明"打包在一起 | 在通道维度拼接输入 |
| CNN网络 | 像X光机扫描包裹,找出破损点 | 3层卷积网络提取特征 |
| 输出层 | 根据扫描结果修复包裹 | 使用反向过程公式生成修复图像 |
6.3 网络参数说明
| 参数类型 | 数量 | 示例 |
|---|---|---|
| 可训练参数 | ~2.4M | 3个Conv2d层权重 |
| 固定参数 | β_t序列(1000个) | 线性增长的噪声方差 |
| 激活函数 | ReLU | 2层使用ReLU激活 |
| 输入尺寸 | 3\\times H\\times W | 通常为 3\\times 256\\times 256 |
| 输出尺寸 | 3\\times H\\times W | 与输入尺寸一致 |
6.4 优化建议
| 优化方向 | 实现方式 | 效果 |
|---|---|---|
| 加速推理 | 使用DDIM加速 | 将1000步压缩到100步 |
| 提升质量 | 加深网络结构 | 使用UNet架构 |
| 内存优化 | 混合精度训练 | 减少显存占用 |
| 多模态扩展 | 添加文本编码器 | 支持文本到图像生成 |
7. 生成模型对比分析
| 模型类型 | 核心原理 | 大白话说明 | 使用领域 | 优势 | 劣势 | 使用普遍性 | 大模型时代用途 |
|---|---|---|---|---|---|---|---|
| CNN | 局部感受野 + 权值共享 | "找特征"的扫描仪,像放大镜看局部 | 图像分类、目标检测 | 特征提取能力强 | 无法处理长距离依赖 | 高 | 作为基础模块用于视觉任务 |
| RNN | 时序记忆单元 | "记流水账"的笔记本,记住前一步的信息 | 语言建模、序列预测 | 处理时序数据 | 梯度消失/爆炸 | 中 | 被Transformer取代 |
| GAN | 生成器 vs 判别器 | "画匠"和"鉴宝师"的博弈 | 图像生成、风格迁移 | 生成质量高 | 训练不稳定 | 中 | 与扩散模型结合使用 |
| DDPM | 逐步去噪 | "修复师"从噪声中还原图像 | 文本到图像、视频生成 | 生成质量极高 | 计算成本高 | 高 | Stable Diffusion核心 |
8. DDPM的领域应用
8.1 图像生成(Stable Diffusion)
- 优势:支持文本到图像生成,细节逼真
- 案例:DALL·E 2、Midjourney v5
- 公式:结合Transformer的CLIP编码器处理文本
8.2 视频生成(Stable Video Diffusion)
- 优势:时空一致性好
- 案例:Runway ML的Gen-2
- 公式:扩展到3D张量处理时空信息
8.3 分子设计(Diffusion for Chemistry)
- 优势:生成符合物理规则的分子
- 案例:DeepMind的AlphaFold Diffusion
- 公式:修改扩散过程以适应分子空间
9. DDPM的优劣势分析
| 特性 | 描述 |
|---|---|
| 优势 | 1. 生成质量极高 2. 理论保证收敛 3. 支持任意分布建模 |
| 劣势 | 1. 计算成本高(需1000步迭代) 2. 推理速度慢 3. 内存占用大 |
| 改进方案 | 1. DDIM加速(确定性去噪) 2. UNet结构优化 3. 混合Transformer架构 |
10. 未来展望
- 与Transformer结合:Stable Diffusion v5已使用Transformer作为UNet组件
- 多模态生成:文本+图像+语音联合生成
- 工业级优化:NVIDIA的TensorRT支持DDPM加速推理
- 科学应用:蛋白质结构预测、药物分子设计
11. 结语
DDPM通过"逐步去噪"的方式,实现了高质量的图像生成,避免了GAN常见的模式崩溃问题。它就像一个耐心的修复师,从完全混乱的噪声中,一点点恢复出清晰的图像。
"DDPM不是直接生成图像,而是通过'修复'噪声来生成图像。"
在实际应用中,DDPM已被用于生成高质量图像(如Stable Diffusion)、视频生成、分子设计等领域。其核心思想"逐步去噪"也启发了其他扩散模型(如DDIM)的发展。
下一篇预告:【人工智能】【深度学习】 ④ Stable Diffusion核心算法解析:从DDPM到文本生成图像的飞跃
本文为原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文链接及本声明。