跳到主要内容

扩散模型原理

本节定位

生成模型有很多路线:

  • GAN 想一次性生成
  • VAE 想学潜空间分布

扩散模型则换了一个非常特别的思路:

先把真实样本一步步弄脏,再学会把它一步步洗干净。

这条思路后来成为图像生成里非常重要的一条主线。

学习目标

  • 理解为什么图像生成是高难问题
  • 理解扩散模型里“加噪”和“去噪”这两个方向
  • 看懂一个最小正向加噪示例
  • 理解模型训练时真正学的是什么
  • 建立对扩散模型整体流程的稳定直觉

一、为什么图像生成这么难?

1.1 先看分类和生成的差别

做分类时,你是在问:

  • 这张图是不是猫?

做生成时,你是在问:

  • 生成一张像猫的图。

这两个任务看起来只差一点,但难度完全不在一个量级。

1.2 真正难在哪?

因为图像空间太大了。
随便生成一堆像素,绝大多数都会看起来像噪声,而不是“合理图片”。

所以生成模型真正要学的是:

怎样从几乎无限的像素组合里,落到那些“像真实图像”的区域。

扩散模型的厉害之处就在于,它没有试图一步到位,而是把问题拆成了很多个更小的去噪步骤。


二、扩散模型最核心的直觉

2.1 正向过程:把图像一步步加噪

如果你有一张真实图像,只要不断往里面加噪:

  • 一开始还能看出结构
  • 后来越来越模糊
  • 最后几乎变成纯噪声

这个过程非常容易定义。

2.2 反向过程:学会一步步去噪

难的部分在反向:

  • 给你一张带噪图
  • 你要猜怎样把噪声去掉一点

如果这个动作做很多步,最后就有机会从噪声里恢复出有结构的图像。

2.3 一个很好记的类比

可以把它想成:

  • 正向:把一张干净照片不断抹上墨
  • 反向:学会怎样一点点把墨去掉

真正难的不是抹脏,而是洗回去。


三、一个最小可运行的正向加噪示例

先不用图片,先看一维向量,方便把“逐步加噪”的过程看清。

import numpy as np

np.random.seed(42)

x0 = np.array([1.0, 0.5, -0.5, -1.0], dtype=np.float32)
print("x0 =", x0)

x = x0.copy()
for step in range(1, 6):
noise = np.random.randn(*x.shape).astype(np.float32) * 0.2
x = 0.8 * x + noise
print(f"step {step}: {np.round(x, 3)}")

3.2 这段代码到底在教什么?

它在教你两个非常关键的事实:

  1. 每一步都保留一部分原始结构
  2. 每一步都混入一部分新的噪声

随着步数越来越多,结构会越来越不清晰。

这就是正向扩散的直觉版本。


四、为什么正向过程容易,反向过程难?

4.1 因为正向过程是你自己定义的

你完全知道:

  • 这一步加了多少噪声
  • 原信号衰减了多少

所以正向过程几乎是“人为可控”的。

4.2 反向过程为什么难?

因为当你只看到一个带噪样本时,你并不知道:

  • 哪部分是原来的结构
  • 哪部分是后面混进去的噪声

这就像你拿到一张被涂脏的纸,但不知道原来图案长什么样。

所以模型真正要学的是:

如何从带噪状态里预测噪声成分。


五、训练时模型到底在学什么?

5.1 一个非常关键的点

扩散模型训练时,通常不是直接让模型“学画图”,而是让它学:

给定带噪样本,预测里面的噪声。

5.2 为什么这很聪明?

因为训练时噪声是你自己加进去的,所以监督信号天然就有:

  • 原样本你知道
  • 噪声你也知道

因此问题就变成了一个比较明确的监督学习任务。

5.3 一个最小“学习目标”示意

import numpy as np

x_clean = np.array([1.0, -0.5, 0.8], dtype=np.float32)
noise = np.array([0.2, -0.1, 0.3], dtype=np.float32)
x_noisy = 0.9 * x_clean + noise

print("clean =", x_clean)
print("noise =", noise)
print("noisy =", x_noisy)

如果模型学会了从 x_noisy 预测 noise
它就能在推理时一步步把噪声剥离掉。


六、采样时为什么要从纯噪声开始?

6.1 因为推理时没有原图可用

生成时并没有 x0,只有噪声。

所以系统通常从:

  • 一团随机噪声

开始,然后反复做:

  1. 预测当前噪声
  2. 去掉一点噪声
  3. 得到更干净一点的状态

6.2 一步步去噪和一步生成的差别

GAN 更像:

  • 一步直接生成

扩散模型更像:

  • 逐步雕刻

这也是为什么扩散模型常常给人一种“更稳但更慢”的感觉。


七、为什么这种路线后来很强?

7.1 训练通常更稳

相比很多 GAN 训练里的对抗不稳定,扩散模型的训练往往更稳定一些。

7.2 条件化能力很自然

一旦你能在去噪过程中加入条件信息,就可以做:

  • 文生图
  • 图像编辑
  • 局部修复

这也是它后来迅速变强的重要原因。


八、扩散模型的代价是什么?

8.1 采样慢

因为不是一步生成,而是很多步去噪。

8.2 计算重

尤其是在高分辨率图像上,成本会比较高。

8.3 所以后来大家都在做什么?

主要就是两件事:

  • 提高采样效率
  • 降低扩散操作的空间成本

这也正好引出下一节:

Stable Diffusion 为什么要把扩散放进 latent space。


九、小结

这一节最重要的不是背公式,而是抓住这条主线:

扩散模型不是直接学会“画图”,而是学会“怎么把带噪样本一步步去噪回有结构的样子”。

只要这个直觉稳了,后面看 Stable Diffusion 的结构就会自然很多。


练习

  1. 改一下本节示例里的衰减系数 0.8,观察结构消失速度变化。
  2. 用自己的话解释:为什么说扩散模型训练更像“学去噪”,而不是“直接学画图”?
  3. 想一想:为什么扩散模型通常会比一步生成的方法更慢?
  4. 如果你要向别人解释扩散模型,怎么用“先弄脏再洗干净”的类比去讲?