此文只记录一般的计算结果及故事框架,不涉及详细推导过程,如需要查看详细过程,请搜索参考链接, 如有错误欢迎批评指正
参考链接
都2023年了,我不允许你还不懂DDPM! - 知乎 (zhihu.com)
扩散模型(一)——DDPM推导笔记-大白话推导_扩散模型公式推导-CSDN博客
一文带你看懂DDPM和DDIM(含原理简易推导,pytorch代码) - 知乎 (zhihu.com)
扩散模型(Diffusion Model)——由浅入深的理解-CSDN博客
DDPM是AIGC的基础模型,这里图像被认为是一种特定分布的采样,为了实现这一目的,原论文作者使用了大量的计算,证明出由随机分布到图像的过程,总体流程如下图:
扩散
最终需求是逆扩散过程,为了得到其函数表达,先来探讨扩散过程:在图像中逐步添加噪声,经过T步后,得到随机噪声的图像, 即(), 仅与当前状态有关,这是一个马尔可夫过程,添加的噪声来自正态分布的采样,且每一步扩散的步长受变量影响, 表示方差序列,得到的表达式:
令:, , 重参数化技巧表示为:
如何一步获取呢,如下:
这里可以写出的表达,替换掉就可以得到的表达式,通过数学归纳法可以得到的关系:
令:, 则
以上就完成了扩散的部分
逆扩散
逆扩散过程为一步一步的去噪,核心的过程是,怎么得到这个过程, 这里用到了贝叶斯:
(正好把先验和后验的顺序换了, 很神奇)
无论是t时刻还是t-1时刻,其都有共同的先验, 所以就有:
扩散是马尔可夫性质的
当前状态只与前一状态有关
在这个表达式中, , , 在前面的扩散过程中均是已经写出表达式的,这里可以直接替换,如下:
其中
替换后一顿化简
已知与的表达式,替换掉,得到概率密度函数:
再经过一顿化简,最终结果如下:
上述函数表示由当前时刻与从t0时刻到当前时刻的噪音来预测t-1时刻的分布
由此可以推断,知道当前时间的分布和对应原图的噪音,就可以得到前一时刻的分布,循环这个步骤就可以得到原图!怎么获得对应原图的噪声,论文选用的网络是UNET,输入和时间步t输出噪音,再代入上式得到前一时刻分布
loss
这里损失函数为KL散度,即两个分布之间的距离,又经过一顿化简和删减后可以近似为L2损失函数, 如下:
式中表示UNET, 为当前时刻的噪音
如上所舒,训练的神经网络为UNET,计算损失使用MSE,约束的是对应时间步加入噪声与网络预测噪声的误差
def loss(self, x0: torch.Tensor, noise: Optional[torch.Tensor] = None):
# Get batch size
batch_size = x0.shape[0]
# Get random $t$ for each sample in the batch
t = torch.randint(0, self.n_steps, (batch_size,), device=x0.device, dtype=torch.long)
if noise is None:
noise = torch.randn_like(x0)
xt = self.q_sample(x0, t, eps=noise)
eps_theta = self.eps_model(xt, t)
# MSE loss
return F.mse_loss(noise, eps_theta)
至此,完成了整个过程,也就是论文中的两个过程