没有手怎么画画?在线等,挺急的
扩散模型原理浅析
阅读完 DDPM 写的笔记,边学边写喵~,有错误请在评论区指正喵~
0x01 背景
如何画出一张以假乱真的图片?现在你有这几种方法:
- 直接拍一张照片,宣称这是你自己画的(笑)。
- 直接把要画的东西摆在纸上,嘿嘿,画完了!
- 找一个画笔,用它来画!(尽管对你的画画能力有要求)
人类画画,就是这么简单直观。我们可以观察物体的形状、颜色、光影,然后用手中的画笔在纸上重现出来。即使技法不够娴熟,但我们至少知道从何下手。
那现在的电脑呢?它们没有眼睛,无法真正"看见"事物;没有手,无法握笔作画;更没有大脑的艺术感知能力。然而,当我们使用 AI 绘图工具时,只需输入一段文字描述,就能得到一张《栩栩如生》的图像(确信)。这些图像甚至能让很多人误以为是真人拍摄的照片。
这就引出了一个有趣的问题:没有感官、没有肢体的计算机,到底是如何创造出如此逼真图像的呢?它们内部究竟发生了什么神奇的过程,才能让一堆冰冷的数字和算法变成富有艺术感的画面?
接下来,我们将介绍在一切背后的故事。
0x02 引言:扩散模型
扩散模型(Diffusion Model)是一种基于概率分布的图像生成模型,它通过生成一个概率分布来模拟图像生成过程。其基本灵感来自非平衡热力学,通过定义一个扩散步骤的马尔可夫链,逐步为图片添加噪声,然后反转添加噪声的过程,最终得到训练数据。
所以在深入了解扩散模型之前,让我们先认识一下马尔可夫链和概率分布。
0x03 马尔可夫链和概率分布
马尔可夫链(Markov Chain)是一种概率图模型,它描述了系统在某一个状态下的下一个状态的概率。可以说是机器学习和人工智能的基石,在强化学习、自然语言处理、金融领域、天气预测、语音识别方面都有着极其广泛的应用。
The future is independent of the past given the present 未来独立于过去,只基于当下。
这句格言很贴切地描述了马尔可夫链的基本原理。所有过去的状态都被保留到了当前的状态,所以基于当下,就可预测未来。
虽然这么说可能有些极端,但是却可以大大简化模型的复杂度,因此马尔可夫链在很多时间序列模型中得到广泛的应用,比如循环神经网络 RNN,隐式马尔可夫模型 HMM 等,当然 MCMC 也需要它。
我们以一个经典的例子来说明:股票专家通过当前股市状态预测未来股票价格。 :::align{center}
:::
以上面这个概率分布为例,假设当前三种状态的概率分布为:
与矩阵优化 DP 类似,矩阵
:::info[可以简单地用下面的程序来实现:]{open}
import numpy as np
P = np.array([[0.9, 0.075, 0.025], [0.15, 0.8, 0.05], [0.25, 0.25, 0.5]], dtype=float)
current_state = np.array([[0.3, 0.4, 0.3]], dtype=float)
for i in range(100):
current_state = np.dot(current_state, P) # 或者 current_state @ P
print(f"Current round {i + 1}: ")
print(current_state)
:::
:::info[运行结果如下:]{open}
Current round: 1
[[ 0.3975 0.4175 0.185 ]]
Current round: 2
[[ 0.463375 0.398375 0.13825 ]]
Current round: 3
[[ 0.507944 0.38548 0.106576]]
...
Current round: 55
[[ 0.624999 0.3125 0.0625]]
Current round: 56
[[ 0.625 0.3125 0.0625]]
Current round: 57
[[ 0.625 0.3125 0.0625]]
...
Current round: 100
[[ 0.625 0.3125 0.0625]]
:::
不难发现,在若干轮后,概率分布已经收敛到某一个值,这个值就是模型所生成的概率分布。因此得出,满足一定条件的马尔可夫链具有稳定性。
什么不是马尔可夫链可以实现的?
现在你有一个袋子,里面装有
对于这个问题,显然我们无法使用马尔可夫链,因为当前状态不仅取决于上一状态,还取决于此前每一次抽球的结果。
0x04 扩散
回到往照片上撒沙子这回事。首先介绍噪声的扩散,在数据当中,不断地加入具有高斯分布的噪声,最开始还具有原始图片的特征,但是随着噪声的不断加入,最后会变为一个纯噪声图片,如图所示:
:::align{center} :::
容易发现,每一个噪声都是在上一噪声基础上生成的,从最初的
从概率角度看,扩散模型的联合分布
0x05 硬的要来了
接下来,让我们细致分析一下其中的每一步,当然,可能会有很多公式,我尽可能把它讲明白。
0x05.1 前向过程的数学表达
在扩散模型的前向过程中,我们从原始数据
基于上述定义,前向过程中从
0x05.2 反向过程的核心
反向过程是扩散模型生成图像的关键,它的目标是从纯噪声
在实际训练中,为了简化模型并提升性能,通常对反向过程的方差和均值做特殊处理。对于方差
而对于均值
0x06 回归应用
有了扩散模型,让我们回归到最初的问题:我们如何用它来生成图像呢?
整体而言,需要下面三个步骤:
0x06.1 文本编码
对于刚刚的 Diffusion Model,它并不能直接处理文字这类非值数据,因此我们需要将文字编码为数值数据,也就是向量(Text Embedding 过程)。在这一步骤中,CLIP 被用来将文字编码为向量,并最终输出为一个特定维度的语义向量。
CLIP 高度依赖于 Transformer 架构,其目标是建立“文本”与“图像”的跨模态语义关联。因而采用“文本编码器 + 图像编码器”的双分支结构。两个编码器分别将文本、图像转换为统一维度的特征向量,再通过对比学习(Contrastive Learning)让“匹配的文本 - 图像对”特征更相似,“不匹配的对”特征更疏远。
你也许在登录一些网站时见过一些 Captcha 验证码,要求你选择符合要求的某张图片,其中一部分这样的验证码被用于收集 CLIP 的训练数据。
0x06.2 噪声生成与去噪
前面我们说过,扩散模型是一个逐步去噪的过程,因此我们需要生成一个包含噪声的初始数据,并逐步去除噪声,最终得到一个接近原始数据的图像。
接下来,把这个纯噪声组成的张量
0x06.3 善后工作
迭代策略与采样方法
在噪声生成与去噪的核心流程中,模型的迭代策略和采样方法直接决定了最终生成图像的质量与效率,这一步也是扩散模型图像生成的关键优化环节。
扩散模型的去噪过程需要通过多步迭代完成,迭代步数
- 更多的迭代步数理论上能让去噪过程更精细,生成图像的细节更丰富、与文本语义的匹配度更高,但会显著增加计算成本,延长生成时间
- 过少的迭代步数则可能导致去噪不充分,图像出现模糊、语义偏离等问题
在实际应用中,通常会根据场景需求选择合适的步数:
- 轻量级场景:采用 50-100 步迭代
- 对质量要求较高的场景:将步数提升至 200-1000 步
模型输出的后处理
经过多步迭代得到最终的图像张量
-
像素值归一化:将模型输出的张量数值映射到图像显示的标准范围(如 0-255 的 RGB 像素值),确保图像能够正常渲染
-
超分辨率增强:对于生成的低分辨率图像,通过超分辨率模型(如 ESRGAN、Real-ESRGAN 等)提升图像分辨率,补充细节纹理,改善画面清晰度
-
降噪与锐化:针对图像可能存在的轻微噪声或模糊问题,采用降噪算法(如非局部均值降噪)和锐化算法(如拉普拉斯锐化)进行优化,提升图像的视觉质感
0x07 总结
所以恭喜你坚持看完了!
总结一下,读完本文,你大概率已经初步了解了扩散模型及其应用。那么接下来,去手搓一个 DALL-E 罢!
另:求赞,打公式眼睛快瞎了……
:::info[参考文献]
- Ho, J., Jain, A., & Abbeel, P. (2020). Denoising diffusion probabilistic models. Advances in Neural Information Processing Systems, 33, 6840-6851.
:::
:::info[关于本文]
本文初稿完成于 10/24/2025,完成后使用 Qwen LLM 校对和二次排版。
依据 CC-BY-NC-SA 4.0 协议授权,欢迎转载、修改、分发,但请务必保留作者署名。
:::