DDPM扩散模型(模型结构图与公式推导)

DDPM扩散模型

一、前置知识

1. 条件概率知识

P(A∣B)=P(AB)P(B)P(A|B) = \frac{P(AB)}{P(B)}P(AB)=P(B)P(AB)

P(ABC)=P(C∣BA)P(BA)=P(C∣BA)P(B∣A)P(A)P(A B C) = P(C|B A)P(BA) = P(C|B A)P(B|A)P(A)P(ABC)=P(CBA)P(BA)=P(CBA)P(BA)P(A)

P(BC∣A)=P(B∣A)P(C∣A,B)P(B C|A) = P(B|A)P(C|A, B)P(BCA)=P(BA)P(CA,B)

P(C∣A,B)=P(BC∣A)P(B∣A)P(C|A, B) = \frac{P(BC| A)}{P(B|A)}P(CA,B)=P(BA)P(BCA)

2. 基于马尔科夫假设的条件概率

如果满足马尔科夫链关系A−>B−>CA -> B -> CA>B>C那么有

P(ABC)=P(C∣BA)P(BA)=P(C∣B)P(B∣A)P(A)P(A B C) = P(C|BA)P(B A) = P(C|B)P(B|A)P(A)P(ABC)=P(CBA)P(BA)=P(CB)P(BA)P(A)

P(BC∣A)=P(B∣A)P(C∣B)P(B C|A) = P(B|A)P(C|B)P(BCA)=P(BA)P(CB)

3. 高斯分布的KL散度公式

对于两个单一变量的高斯分布 P 和 Q 而言,它们的 KL 散度为: KL(P,Q)=log⁡σ1σ2+σ12+(μ1−μ2)22σ22−12KL(P, Q) = \log{\frac{\sigma_1}{\sigma_2}} + \frac{\sigma_1^2 + (\mu_1 - \mu_2)^2}{2 \sigma_2^2} - \frac{1}{2}KL(P,Q)=logσ2σ1+2σ22σ12+(μ1μ2)221

KL 散度,又称为相对熵,描述两个概率分布P和Q的差异和相似性,用DKL(P∣∣Q)D_{KL}(P||Q)DKL(P∣∣Q)表示

在这里插入图片描述

显然,散度越小,说明概率Q与概率P之间越接近,那么估计的概率分布与真实的概率分布也就越接近。

KL 散度的性质:

  1. 非对称性:DKL≠DKL(Q∣∣P)D_{KL} \neq D_{KL}(Q || P)DKL=DKL(Q∣∣P)
  2. DKL(P∣∣Q)≥0D_{KL}(P || Q) \geq 0DKL(P∣∣Q)0,仅在P=QP = QP=Q时等于0

4. 参数重整化

如果希望从高斯分布N(μ,σ2)N(\mu, \sigma^2)N(μ,σ2)中采样(μ\muμ:表示均值,σ2\sigma^2σ2:表示方差),可以先从标准分布N(0,1)N(0, 1)N(0,1)采样处zzz,再得到σ×z+μ\sigma \times z + \muσ×z+μ ,这样做的好处是将随机性转移到了zzz这个常量上了,而σ\sigmaσμ\muμ则当做仿射变换网络的一部分。

二、Diffusion Model流程

在这里插入图片描述

x0x_0x0是初始数据(一个初始的图片),xTx_TxT是最终的图片(一个纯噪声的图片)。

  1. x0∼xTx_0 \sim x_Tx0xT的过程是一个加噪过程,每次从q(xt∣xt−1)q(x_t|x_{t - 1})q(xtxt1)分布中取噪声,然后添加到前一个时间步的图片数据中,这样经过T个时间步,我们就能得到一个纯噪声的图片了。
  2. xT∼x0x_T \sim x_0xTx0的过程是一个去噪过程,每次从pθ(xt−1∣xt)p_\theta(x_{t - 1}|x_t)pθ(xt1xt)分布中取噪声,然后使前一个时间步的图片数据减去该噪声,这样经过T个时间步,我们就能得到原始的图片了。

其中q(xt∣xt−1)q(x_t|x_{t - 1})q(xtxt1)是自己设定的一个加噪分布,而pθ(xt−1∣xt)p_\theta(x_{t - 1}|x_t)pθ(xt1xt)是需要神经网络去学习的一个分布,我们会使用参数分布来去对该分布做估计,由于使用了参数重整化的思想(σ×ϵ+μ\sigma \times \epsilon + \muσ×ϵ+μ,其中σ\sigmaσ是分布的方差,μ\muμ表示的是分布的均值,ϵ\epsilonϵ是从标准正态分布中随机采样的一个值),我们加噪过程是从一个标准正态分布中随机采样一个值,然后再进行参数重整化,依据μ\muμσ\sigmaσ得到特定分布下的噪声,而去噪过程是利用神经网络学习这个噪声,然后在每个时间步上减去预测出的噪声。

三、加噪过程

给定初始数据分布x0∼q(x)x_0 \sim q(x)x0q(x),可以不断地向分布中添加高斯噪声,该噪声的方差是以固定值βt\beta_tβt而确定的,均值是以固定值βt\beta_tβt和当前ttt时刻的数据xtx_txt决定的。这个过程是一个马尔科夫链过程,随着ttt的不断增大,不断的向数据中添加噪声,最终数据分布xtx_txt变成了一个各向独立的高斯分布。

噪声的分布可以表示如下:

q(xt∣xt−1)=N(xt;1−βt⋅xt−1,βtI)q(x_t|x_{t - 1}) = N(x_t; \sqrt{1 - \beta_t}\cdot x_{t - 1}, \beta_tI)q(xtxt1)=N(xt;1βt xt1,βtI) 其中1−βt⋅xt−1\sqrt{1 - \beta_t}\cdot x_{t- 1}1βt xt1表示该分布的均值,βtI\beta_t IβtI 表示方差(III表示单位矩阵)。

那么有:xt=1−βtxt−1+βtztx_t = \sqrt{1 - \beta_t}x_{t - 1} + \sqrt{\beta_t} z_txt=1βt xt1+βt zt,其中1−βt\sqrt{1 - \beta_t}1βt 是一个控制噪声强度的系数,βt\beta_tβt是一个添加噪声比例的系数,论文中说明,当分布越来月接近噪声分布的时候,可以将βt\beta_tβt变得大一点,这样做可以再初始的时候βt\beta_tβt很小,那么添加的噪声也就很小,而1−βt\sqrt{1 - \beta_t}1βt 会很大,那么将会保留更多原来数据的特征,再最后的时候βt\beta_tβt很大,那么添加的噪声也会更大,而1−βt\sqrt{1 - \beta_t}1βt 也就会更大,那么将会去除掉更多原来数据的特征。

设定噪声的方差βt∈(0,1)\beta_t \in (0, 1)βt(0,1),并且 βt\beta_tβt 随着 ttt 的增大而增大。

通过上述的分布,我们可以将原始数据图片x0x_0x0通过q(x1∣x0)q(x_1| x_0)q(x1x0)分布进行加噪,从而得到x1x_1x1,然后再通过q(x2∣x1)q(x_2| x_1)q(x2x1)分布进行对x1x_1x1

### 关于DDPM模型的资料、实现教程 #### 1. **理论基础** 扩散概率模型(Diffusion Probabilistic Models, DPMs),特别是去噪扩散概率模型(Denoising Diffusion Probabilistic Models, DDPMs),是一种基于连续时间框架的概率生成模型。其核心思想是从噪声中逐步恢复清晰的数据样本,通过一系列前向过程引入噪声,并利用反向过程去除这些噪声[^4]。 为了深入理解DDPM的工作原理及其背后的数学机制,可以参考以下资源: - 文章《The Annotated Diffusion Model》提供了一个详细的注解版本,帮助初学者快速掌握扩散模型的核心概念和公式推导[^1]。 - 另外,《How does Stable Diffusion work?》是一篇通俗易懂的文章,适合希望了解扩散模型实际应用场景的人群。 #### 2. **代码实现** 对于想要动手实践的人来说,以下是几个值得推荐的开源项目和教程: - PyTorch-DDPM 是一个专注于PyTorch框架下的扩散模型教学工具包。它不仅包含了完整的训练脚本,还附带了 `ddpm_example.yml` 配置文件作为入门指南[^2]。该配置文件涵盖了模型定义、数据集加载以及训练超参数调整等多个方面,非常适合新手上手。 - 如果更倾向于阅读简洁明了的Python代码,则可以从 GitHub 上搜索关键词 “pytorch beginner ddpm”,找到许多由社区贡献的小型实验性项目。这类项目的优点在于结构简单且易于扩展。 #### 3. **进阶学习材料** 当具备一定基础知识之后,可以通过下面几份文档进一步提升自己的技能水平: - 大白话AI系列文章——图像生成模型章节专门讨论了包括但不限于VAE、GAN在内的多种主流生成对抗网络家族成员之间的异同点,同时也介绍了如何过渡至最新的AIGC领域趋势[^3]。 - 对学术论文感兴趣的读者可以直接查阅 Jonathan Ho 等人在 NeurIPS 2020 发表的经典之作《Denoising Diffusion Probabilistic Models》,这是现代版DDPM算法诞生的重要里程碑之一。 ```python import torch from torchvision import datasets, transforms from pytorch_lightning import Trainer, LightningModule class SimpleDDPM(LightningModule): def __init__(self, config_path="ddpm_example.yml"): super().__init__() self.config = load_config(config_path) def forward(self, x_t, timesteps=None): pass if __name__ == "__main__": transform = transforms.Compose([ transforms.ToTensor(), lambda x: (x * 2) - 1, ]) dataset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform) dataloader = torch.utils.data.DataLoader(dataset, batch_size=64, shuffle=True) ``` 上述代码片段展示了一个简化版的DDPM类初始化逻辑及数据预处理流程示例。 --- ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值