扩散模型(Diffusion Models)详解

扩散模型(Diffusion Models)详解

扩散模型(Diffusion Models)在近几年成为了生成对抗网络(GAN)之外的又一高质量生成模型的主要方向。它的中心理念可以概括为:「先把一张清晰的图逐渐加噪,最后变成纯随机噪声;然后训练一个神经网络去逆向地一步步清除噪声,最终还原到清晰的原图」。本篇将用直观的方式,并结合详细数学公式,来解释扩散模型的运作原理与实现流程。


一、为什么叫“扩散”?

在物理上,“扩散”常指例如一滴墨汁在水中慢慢扩散成均匀分布的过程。对于数据而言,则可以想象:把一张图像视为起始状态,每一步添上一点高斯噪声——图像就越来越模糊,最终完全变成像水中“均匀分布的墨汁”一样的纯噪声。 接下来要做的,就是 “逆向扩散”:假设我们手中只有一张纯随机噪声的图像,通过网络一步步“去噪”,让它回到那幅清晰图像。

在训练阶段,我们知道真实图像和各步噪声图像的对应关系;网络学到如何在每个阶段把噪声减去一点点,从而逐步逼近真实图像分布。


二、数学原理

1. 正向扩散(Forward Diffusion)

令数据点 x 0 ∈ R d \mathbf{x}_0 \in \mathbb{R}^d x0Rd 表示原始样本(如图像像素),我们定义一个“加噪”马尔可夫链:
x 0    →    x 1    →    …    →    x T \mathbf{x}_0 \;\to\; \mathbf{x}_1 \;\to\; \dots \;\to\; \mathbf{x}_T x0x1xT
其中每一步遵循
q ( x t ∣ x t − 1 ) =    N  ⁣ ( x t ∣ 1 − β t   x t − 1 ,    β t I ) , q(\mathbf{x}_t \mid \mathbf{x}_{t-1}) =\; \mathcal{N}\!\Bigl(\mathbf{x}_t \mid \sqrt{1-\beta_t}\,\mathbf{x}_{t-1},\;\beta_t \mathbf{I}\Bigr), q(xtxt1)=N(xt1βt xt1,βtI),
β t \beta_t βt是第 t t t步的噪声强度( 0 < β 1 < ⋯ < β T < 1 0<\beta_1<\dots<\beta_T<1 0<β1<<βT<1)。
直觉:在第 t t t步,我们把上一步 x t − 1 \mathbf{x}_{t-1} xt1保留 1 − β t \sqrt{1-\beta_t} 1βt 那部分,另外 β t \beta_t βt的部分全改为随机高斯噪声,让图像变得比上一时刻更模糊。

通俗解释:想象有人在一幅画上撒了一点灰尘(噪声),然后下一步再撒更多灰尘,直到画面完全看不清。这便是“正向扩散”。

累积加噪公式

若我们一步步加噪到第 t t t步,可写
q ( x t ∣ x 0 ) =    N  ⁣ ( x t    ∣    α ˉ t   x 0 ,    ( 1 − α ˉ t ) I ) , q(\mathbf{x}_t \mid \mathbf{x}_0) =\; \mathcal{N}\!\Bigl(\mathbf{x}_t \;\big|\; \sqrt{\bar{\alpha}_t}\,\mathbf{x}_0,\;\bigl(1-\bar{\alpha}_t\bigr)\mathbf{I}\Bigr), q(xtx0)=N(xt αˉt x0,(1αˉt)I),
其中 α t = 1 − β t \alpha_t = 1-\beta_t αt=1βt α ˉ t = ∏ s = 1 t α s \bar{\alpha}_t = \prod_{s=1}^t \alpha_s αˉt=s=1tαs
这表示:只要知道第0步的图像 x 0 \mathbf{x}_0 x0,就能一次性地生成第 t t t步的带噪图像,少了迭代操作。


2. 逆向去噪(Reverse Diffusion)

在推理(采样)阶段,我们希望从纯随机噪声 x T \mathbf{x}_T xT开始,反向地一步步去噪,得到 x 0 \mathbf{x}_0 x0
若定义了
p θ ( x t − 1 ∣ x t ) , t = T , … , 1 p_\theta(\mathbf{x}_{t-1} \mid \mathbf{x}_t), \quad t=T,\dots,1 pθ(xt1xt),t=T,,1
则可采样出一个“逆向马尔可夫链”。如何确定这个条件分布?由于正向过程是高斯加噪,我们可以用贝叶斯法得到

q ( x t − 1 ∣ x t , x 0 )    =    N ( x t − 1    ∣    μ ~ t ( x t , x 0 ) ,    σ ~ t 2 I ) , q(\mathbf{x}_{t-1}\mid \mathbf{x}_t,\mathbf{x}_0) \;=\; \mathcal{N}\Bigl(\mathbf{x}_{t-1} \;\big|\; \tilde{\mu}_t(\mathbf{x}_t,\mathbf{x}_0),\; \tilde{\sigma}^2_t \mathbf{I}\Bigr), q(xt1xt,x0)=N(xt1 μ~t(xt,x0),σ~t2I),
这个是真实分布,但它依赖 x 0 \mathbf{x}_0 x0,在实际生成时未知。
因此,我们用神经网络 θ \theta θ来近似
p θ ( x t − 1 ∣ x t ) ≈ q ( x t − 1 ∣ x t , x 0 ) , p_\theta(\mathbf{x}_{t-1}\mid \mathbf{x}_t) \approx q(\mathbf{x}_{t-1}\mid \mathbf{x}_t,\mathbf{x}_0), pθ(xt1xt)q(xt1xt,x0),

并把它再写成

p θ ( x t − 1 ∣ x t ) = N  ⁣ ( x t − 1 ∣ μ θ ( x t , t ) ,   Σ θ ( x t , t ) ) . p_\theta(\mathbf{x}_{t-1}\mid \mathbf{x}_t) =\mathcal{N}\!\Bigl(\mathbf{x}_{t-1} \mid \mu_\theta(\mathbf{x}_t, t),\,\Sigma_\theta(\mathbf{x}_t, t)\Bigr). pθ(xt1xt)=N(xt1μθ(xt,t),Σθ(xt,t)).

通俗解释:要逆向从一堆灰尘变回清晰图,就要知道“这一点灰尘来自何处”?这是未知的。我们只好用网络学习在第 t t t步时“如何去掉部分灰尘”来逼近真实无噪状态。


3. 训练目标

我们要让网络学会在每个 t t t步去噪的方式,使得 x t − 1 \mathbf{x}_{t-1} xt1逼近真实 x t − 1 \mathbf{x}_{t-1} xt1
等价地,我们最小化
L = E   q ( x 0 , … , x T ) [ ∑ t = 1 T D K L  ⁣ ( q ( x t − 1 ∣ x t , x 0 )   ∥   p θ ( x t − 1 ∣ x t ) ) ] . \mathcal{L}= \mathbb{E}_{\,q(\mathbf{x}_0,\dots,\mathbf{x}_T)}\Bigl[ \sum_{t=1}^T D_{\mathrm{KL}}\!\bigl( q(\mathbf{x}_{t-1}\mid \mathbf{x}_t,\mathbf{x}_0) \,\|\, p_\theta(\mathbf{x}_{t-1}\mid \mathbf{x}_t) \bigr) \Bigr]. L=Eq(x0,,xT)[t=1TDKL(q(xt1xt,x0)pθ(xt1xt))].

为方便,常写成噪声预测的MSE形式:

L = E t , x 0 , ϵ   [ ∥ ϵ − ϵ θ ( x t ,   t ) ∥ 2 ] , \mathcal{L}= \mathbb{E}_{t,\mathbf{x}_0,\epsilon}\,\Bigl[ \|\epsilon - \epsilon_\theta(\mathbf{x}_t,\,t)\|^2 \Bigr], L=Et,x0,ϵ[ϵϵθ(xt,t)2],
其中 x t = α ˉ t   x 0 + 1 − α ˉ t   ϵ \mathbf{x}_t = \sqrt{\bar{\alpha}_t}\,\mathbf{x}_0 + \sqrt{1-\bar{\alpha}_t}\,\epsilon xt=αˉt x0+1αˉt ϵ ϵ ∼ N ( 0 , I ) \epsilon\sim \mathcal{N}(0,\mathbf{I}) ϵN(0,I)
用大白话网络只要学会:给定“带噪的图像 x t \mathbf{x}_t xt”和时间步 t t t,输出对应的噪声 ϵ \epsilon ϵ”就好;然后我们就能“减去”这个噪声。


三、流程概述

  1. 训练

    • 采样一幅真实图像 x 0 \mathbf{x}_0 x0
    • 选随机 t t t,合成 x t \mathbf{x}_t xt
    • 令网络 ϵ θ \epsilon_\theta ϵθ输出噪声预测,与真实 ϵ \epsilon ϵ比对MSE。
    • 更新参数,反复迭代。
  2. 生成

    • 采样纯噪声 x T \mathbf{x}_T xT
    • t = T t=T t=T到1顺序:用网络 ϵ θ ( x t , t ) \epsilon_\theta(\mathbf{x}_t,t) ϵθ(xt,t)去掉部分噪声,得到 x t − 1 \mathbf{x}_{t-1} xt1
    • 最终得 x 0 \mathbf{x}_0 x0便是合成数据。

四、扩散模型的主要类型

  1. DDPM: Ho等人提出的Denoising Diffusion Probabilistic Models,是最基础的范式;
  2. LDM: Latent Diffusion Models,将扩散过程放到低维潜在空间,极大减少计算量;
  3. DPM-Solver等:专注于加速生成的算法,减少迭代步数;
  4. 条件扩散:在网络输入额外条件,如文本、类标签等,实现可控生成(如Stable Diffusion)。

五、与GAN/VAE相比

特征扩散模型(DM)GANVAE
训练稳定性高,相对无模式崩溃低,易不稳定,模式崩溃中等,基于变分推断
生成质量高,细节丰富高,但易出现模式缺失或崩溃一般较清晰度略逊
显式概率解释有,基于似然、KL散度无显式似然有(ELBO)
推断速度慢,多步迭代快,单次前向传递快,同上
多样性避免模式崩溃,样本多样可能模式崩溃尚可

六、应用与案例

  1. 文本到图像:如Stable Diffusion,在文本提示下生成多样且细节丰富的图像;
  2. 图像修复、超分辨率:可用逆向扩散去除局部噪声/模糊并恢复细节;
  3. 医学成像:MRI、CT重建;减少扫描时间;
  4. 音频/语音:Text-to-Speech或音频去噪,多步过程显著提升合成质量;
  5. 多模态生成:联合文本、图像、音频等信息进行跨模态合成。

七、优缺点

优点

  1. 质量高:生成图像细节逼真,不易出现GAN那样的模式崩溃;
  2. 训练稳定:只需回归噪声,不需要对抗式两网络博弈;
  3. 概率解释:具备显式似然、易分析理论性质;
  4. 多样性:生成的样本丰富多彩。

缺点

  1. 生成速度慢:需多步迭代去噪;
  2. 计算/显存需求大:在高分辨率或大步数下负担沉重;
  3. 网络结构复杂:如UNet通常较大;噪声调度策略等超参数多;
  4. 难应用于离散数据:如文本场景需特殊设计。

八、示例代码(PyTorch

以下给出一个简化版扩散模型,用于MNIST数据的去噪训练与采样示例。

import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt

# ====== 1. 简易 UNet-like 网络 ======
class SimpleUNet(nn.Module):
    def __init__(self, in_channels=1, out_channels=1):
        super().__init__()
        self.down = nn.Sequential(
            nn.Conv2d(in_channels, 64, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.Conv2d(64, 128, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2)
        )
        self.up = nn.Sequential(
            nn.ConvTranspose2d(128, 64, kernel_size=2, stride=2),
            nn.ReLU(),
            nn.Conv2d(64, out_channels, kernel_size=3, padding=1)
        )

    def forward(self, x):
        x_enc = self.down(x)
        x_dec = self.up(x_enc)
        return x_dec


# ====== 2. 正向扩散过程 ======
def forward_diffusion(x0, t, beta):
    """
    在给定时间步t下,为x0添加噪声,得到 x_t,并返回噪声本身。
    x0: (B,1,28,28)
    t: (B,)
    beta: 长度T的1D张量
    """
    noise = torch.randn_like(x0)
    sqrt_alpha = torch.sqrt(1 - beta[t]).view(-1,1,1,1)
    sqrt_beta  = torch.sqrt(beta[t]).view(-1,1,1,1)
    x_t = sqrt_alpha * x0 + sqrt_beta * noise
    return x_t, noise

# ====== 3. 逆向生成过程 ======
@torch.no_grad()
def reverse_diffusion(model, xT, beta):
    model.eval()
    T = len(beta)
    x = xT
    for t in reversed(range(T)):
        # 预测噪声
        noise_pred = model(x)
        # 简化逆向更新 (仅演示)
        alpha_t = 1 - beta[t]
        x = (x - torch.sqrt(1-alpha_t)*noise_pred) / (torch.sqrt(alpha_t)+1e-7)
    return x

# ====== 4. 数据加载与训练 ======
device = "cuda" if torch.cuda.is_available() else "cpu"
T = 200
beta_start, beta_end = 0.0001, 0.02
beta = torch.linspace(beta_start, beta_end, T).to(device)

transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.5,),(0.5,))
])
dataset = datasets.MNIST(root='data', train=True, download=True, transform=transform)
loader = DataLoader(dataset, batch_size=64, shuffle=True)

model = SimpleUNet().to(device)
optimizer = optim.Adam(model.parameters(), lr=1e-3)
criterion = nn.MSELoss()

epochs = 3
for epoch in range(epochs):
    total_loss = 0
    model.train()
    for x, _ in loader:
        x = x.to(device)
        # 随机步数
        t = torch.randint(0, T, (x.size(0),), device=device)
        x_t, noise_true = forward_diffusion(x, t, beta)
        noise_pred = model(x_t)
        loss = criterion(noise_pred, noise_true)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        total_loss += loss.item()
    print(f"Epoch [{epoch+1}/{epochs}], Loss = {total_loss/len(loader):.4f}")

# ====== 5. 推理:从噪声生成样本 ======
with torch.no_grad():
    x_init = torch.randn(1,1,28,28, device=device)
    x_gen  = reverse_diffusion(model, x_init, beta)

# 显示结果
plt.imshow(x_gen.squeeze().cpu().numpy(), cmap='gray')
plt.title("Generated Sample via Simplified Diffusion")
plt.axis('off')
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102

代码流程说明

  • 正向加噪(forward_diffusion
    训练阶段每次会随机抽一个时间步 t t t,在真实图像上添加噪声,用于监督网络学习“如何去除这一步的噪声”。这样,网络就知道在各个时刻该减掉多少噪声、如何恢复真图。

  • 逆向去噪(reverse_diffusion
    采样阶段从纯噪声开始,逆序地一步步用网络预测并消除噪声,直到恢复出最终图像。该过程模拟了一个“反扩散马尔可夫链”。

  • 网络结构
    这里用的是简化版 UNet:先卷积提取特征并下采样,再反卷积上采样还原,用于输出对噪声的估计。

  • 训练数据与流程

    • MNIST 数据:简单灰度手写数字(28×28),做标准化后加载。
    • 每个batch:选随机步数 t t t,合成带噪图像 x t x_t xt;网络输出噪声 ϵ ^ \hat{\epsilon} ϵ^,与真噪声比对做MSE。
    • 训练若干轮后,模型学会“在任意步 t t t”去除对应程度的噪声。
  • 采样
    给随机噪声 x T \mathbf{x}_T xT,逐步逆向 x t → x t − 1 \mathbf{x}_t \to \mathbf{x}_{t-1} xtxt1,多步迭代后得到 x 0 \mathbf{x}_0 x0。这就是生成出的数字图像。


九、常见Q&A

  1. 训练为什么不会像GAN那样不稳定?
    因为扩散模型只需要回归噪声(MSE目标),而不需对抗博弈,不会出现模式崩溃或梯度平衡困难。

  2. 如何提升生成速度?

    • 使用加速采样(如 DDIM、DPM-Solver),减少迭代步数;
    • 使用潜在扩散(LDM)在低维空间进行扩散,少运算量。
  3. 为什么要加噪这么多步?

    • 步数越多,逆向去噪越细致,生成质量越高;
    • 但也拖慢生成速度,需要在质量与速度间权衡。
  4. 可否用于文本生成?

    • 是的,但文字是离散数据,需要在embedding或潜在表示上进行扩散,或结合特殊离散扩散策略。
  5. UNet是必须的吗?

    • 并非必须,但它在多尺度特征提取和还原上表现良好,是去噪任务中比较理想的结构。
  6. 如何评价生成效果?

    • 常用FID、IS等指标衡量分布与多样性;或可视化观察生成质量。
  7. 超参有哪些关键?

    • 噪声调度( β t \beta_t βt策略)、网络大小、训练步数、batch大小等都可能影响效果。
  8. 扩散模型是否只适合图像?

    • 并不局限,音频、3D形状、视频、医学数据等都可应用,只要能定义合适的加噪-去噪过程。
  9. 稳定扩散(Stable Diffusion)是啥?

    • 一种潜在扩散模型(LDM),并结合文本条件。其关键在潜在空间扩散、裁剪后记分和文生图等技巧。

十、结语

扩散模型透过“正向加噪—逆向去噪”的可解释马尔可夫链实现了高品质的数据生成和明确的概率表征。尽管多次迭代导致生成速度略慢,但在稳定性、多样性与细节保真度方面表现优异,也避免了GAN中的训练不稳定和模式崩溃问题。随着加速采样、潜在扩散和条件扩散等技术兴起,扩散模型愈发适合各类高维数据(图像、音频、文本、医学等),正成为深度生成学习不可或缺的重要分支。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DuHz

喜欢就支持一下 ~ 谢谢啦!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

举报

选择你想要举报的内容(必选)
  • 内容涉黄
  • 政治相关
  • 内容抄袭
  • 涉嫌广告
  • 内容侵权
  • 侮辱谩骂
  • 样式问题
  • 其他
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回顶部