Diffusion Models

巴斯扩散模型python 巴斯扩散模型推导_巴斯扩散模型python

图中:巴斯扩散模型python 巴斯扩散模型推导_人工智能_02为图像,巴斯扩散模型python 巴斯扩散模型推导_巴斯扩散模型python_03为采样自正态分布的噪音

扩散模型**是受非平衡热力学的启发。它们定义一个扩散步骤的马尔可夫链,逐渐向数据添加随机噪声,然后学习逆扩散过程,从噪声中构建所需的数据样本。与VAE或流动模型不同,扩散模型是用固定的程序学习的,而且隐变量具有高维度。

训练阶段,是在图片中添加噪声,给网络输入这一张添加噪声的图片,网络需要预测的则是添加的噪声。

使用阶段,由随机生成的噪声,使用网络预测添加了什么噪声,然后逐步去除噪声,直到还原。

1、扩散过程

  • 扩散的过程,是不断地逐步向图片中添加噪声,直到图像完全变为纯噪声;
  • 添加的噪声为高斯噪声,而后一时刻都是由前一时刻的图像增加噪声得到的。

添加噪声的过程:

这里定义了两个参数巴斯扩散模型python 巴斯扩散模型推导_深度学习_04巴斯扩散模型python 巴斯扩散模型推导_巴斯扩散模型python_05;(巴斯扩散模型python 巴斯扩散模型推导_数据_06的范围为0~巴斯扩散模型python 巴斯扩散模型推导_深度学习_07之间的整数,巴斯扩散模型python 巴斯扩散模型推导_巴斯扩散模型python_05巴斯扩散模型python 巴斯扩散模型推导_巴斯扩散模型python_09变化到巴斯扩散模型python 巴斯扩散模型推导_巴斯扩散模型python_10,是逐渐变大的,论文中是从0.0001等量的增加巴斯扩散模型python 巴斯扩散模型推导_深度学习_07次,直到0.002 )

巴斯扩散模型python 巴斯扩散模型推导_深度学习_04巴斯扩散模型python 巴斯扩散模型推导_巴斯扩散模型python_05的关系为:

巴斯扩散模型python 巴斯扩散模型推导_数据_14

巴斯扩散模型python 巴斯扩散模型推导_深度学习_07表示的是,由图片通过逐步添加噪声直至完全变为纯噪声的过程所需要经历的次数,也就是图片需要总计需要添加噪声的步数。而巴斯扩散模型python 巴斯扩散模型推导_数据_06则代表的是巴斯扩散模型python 巴斯扩散模型推导_深度学习_07中具体的某一步。

则给图像添加噪声的过程的表达式可以写为:

巴斯扩散模型python 巴斯扩散模型推导_人工智能_18

巴斯扩散模型python 巴斯扩散模型推导_数据_19表示的是第巴斯扩散模型python 巴斯扩散模型推导_数据_06扩散步时,添加噪声后的图片,而巴斯扩散模型python 巴斯扩散模型推导_数据_21是第巴斯扩散模型python 巴斯扩散模型推导_巴斯扩散模型python_22时刻所获得的图片;巴斯扩散模型python 巴斯扩散模型推导_人工智能_23表示的是巴斯扩散模型python 巴斯扩散模型推导_数据_06时刻所添加的噪声,该噪声采样自标准正态分布巴斯扩散模型python 巴斯扩散模型推导_巴斯扩散模型python_25

那么可以依照公式(2)依次从原始图像巴斯扩散模型python 巴斯扩散模型推导_人工智能_02逐步添加噪声,扩散至巴斯扩散模型python 巴斯扩散模型推导_数据_27

巴斯扩散模型python 巴斯扩散模型推导_计算机视觉_28

巴斯扩散模型python 巴斯扩散模型推导_深度学习_29

……

巴斯扩散模型python 巴斯扩散模型推导_人工智能_18

……

巴斯扩散模型python 巴斯扩散模型推导_数据_31

由此可以看出巴斯扩散模型python 巴斯扩散模型推导_巴斯扩散模型python_05逐渐增加,相应的巴斯扩散模型python 巴斯扩散模型推导_深度学习_04逐渐减小,巴斯扩散模型python 巴斯扩散模型推导_计算机视觉_34则是逐渐增大的,也就是说,添加的噪声是逐步增加的,而原始图像的比例是逐渐减小的,并且噪声添加的程度是逐次扩大的。

但对网络的训练,数据是需要随机采样的,每次采样到巴斯扩散模型python 巴斯扩散模型推导_数据_06时刻的时候,都从巴斯扩散模型python 巴斯扩散模型推导_人工智能_02开始递推则太过于繁琐。

所以需要一次就计算出来:

将式 :巴斯扩散模型python 巴斯扩散模型推导_数据_37带入(2)式中,可得

巴斯扩散模型python 巴斯扩散模型推导_数据_38

式子展开为:

巴斯扩散模型python 巴斯扩散模型推导_巴斯扩散模型python_39

巴斯扩散模型python 巴斯扩散模型推导_计算机视觉_40

其中每次加入的噪声——巴斯扩散模型python 巴斯扩散模型推导_巴斯扩散模型python_41——都是服从正态分布 巴斯扩散模型python 巴斯扩散模型推导_巴斯扩散模型python_25

所以可以将

巴斯扩散模型python 巴斯扩散模型推导_巴斯扩散模型python_43巴斯扩散模型python 巴斯扩散模型推导_人工智能_23之间的系数合并在一起,因为正太分布乘以一个系数,只改变方差,而巴斯扩散模型python 巴斯扩散模型推导_巴斯扩散模型python_45

所以

巴斯扩散模型python 巴斯扩散模型推导_人工智能_46

巴斯扩散模型python 巴斯扩散模型推导_深度学习_47

巴斯扩散模型python 巴斯扩散模型推导_人工智能_48

再将巴斯扩散模型python 巴斯扩散模型推导_深度学习_49带入上式,循环往复,将巴斯扩散模型python 巴斯扩散模型推导_深度学习_50带入,可得

巴斯扩散模型python 巴斯扩散模型推导_数据_51

巴斯扩散模型python 巴斯扩散模型推导_数据_52

其中巴斯扩散模型python 巴斯扩散模型推导_数据_53表示从巴斯扩散模型python 巴斯扩散模型推导_人工智能_54巴斯扩散模型python 巴斯扩散模型推导_深度学习_04的连乘

2、训练过程

因此,扩散模型的训练过程如下:

巴斯扩散模型python 巴斯扩散模型推导_巴斯扩散模型python_56

  1. 从数据集中随机抽选一张图片,
  2. 随机从1~T中抽取一个扩散步,
  3. 按照式(3)计算得到 巴斯扩散模型python 巴斯扩散模型推导_深度学习_57
  4. 输入网络,得到输出,输出同添加的噪声做损失,更新梯度,
  5. 反复训练,直至满意。

详细训练过程的代码过程如下:

for i, (x_0) in enumerate(tqdm_data_loader):  # 由数据加载器加载数据,
	x_0 = x_0.to(device)  # 将数据加载至相应的运行设备(device)
    t = torch.randint(1, T, size=(x_0.shape[0],), device=device)  # 对每一张图片随机在1~T的扩散步中进行采样
    sqrt_alpha_t_bar = torch.gather(sqrt_alphas_bar, dim=0, index=t).reshape(-1, 1, 1, 1)  # 取得不同t下的 根号下alpha_t的连乘
    """取得不同t下的 根号下的一减alpha_t的连乘"""
    sqrt_one_minus_alpha_t_bar = torch.gather(sqrt_one_minus_alphas_bar, dim=0, index=t).reshape(-1, 1, 1, 1)
    noise = torch.randn_like(x_0).to(device)  # 从标准正态分布中采样得到z
    x_t = sqrt_alpha_t_bar * x_0 + sqrt_one_minus_alpha_t_bar * noise  # 计算x_t
    out = net_model(x_t, t)  # 将x_t输入模型,得到输出
    loss = loss_function(out, noise) # 将模型的输出,同添加的噪声做损失
    optimizer.zero_grad()  # 优化器的梯度清零
    loss.backward()  # 由损失反向求导
    optimizer.step()  # 优化器更新参数

3、正向使用过程

使用过程是从巴斯扩散模型python 巴斯扩散模型推导_数据_27一步一步取出噪声,推测出巴斯扩散模型python 巴斯扩散模型推导_人工智能_02

也就是说,需要在已知巴斯扩散模型python 巴斯扩散模型推导_数据_27的情况下,先反推巴斯扩散模型python 巴斯扩散模型推导_数据_21,然后推巴斯扩散模型python 巴斯扩散模型推导_数据_62……最终推测得到巴斯扩散模型python 巴斯扩散模型推导_人工智能_02

根据贝叶斯公式推导为:
巴斯扩散模型python 巴斯扩散模型推导_巴斯扩散模型python_64
则整个算法为:

巴斯扩散模型python 巴斯扩散模型推导_人工智能_65

  1. 巴斯扩散模型python 巴斯扩散模型推导_人工智能_66随机采样自标准正态分布;
  2. 从T到1开始循环,
  3. 按照上述公式计算巴斯扩散模型python 巴斯扩散模型推导_巴斯扩散模型python_67,依次往复,其中巴斯扩散模型python 巴斯扩散模型推导_数据_68为网络模型,输入的是巴斯扩散模型python 巴斯扩散模型推导_深度学习_57步的结果和第t步,因为模型要对每一步的位置进行编码,巴斯扩散模型python 巴斯扩散模型推导_计算机视觉_70取样至标准正态分布,在t为最后一步的时候,z取零

具体代码如下:

for t_step in reversed(range(T)):  # 从T开始向零迭代
    t = t_step
    t = torch.tensor(t).to(device)

    z = torch.randn_like(x_t,device=device) if t_step > 0 else 0  # 如果t大于零,则采样自标准正态分布,否则为零
    """按照公式计算x_{t-1}"""
    x_t_minus_one = torch.sqrt(1/alphas[t])*(x_t-(1-alphas[t])*model(x_t, t.reshape(1,))/torch.sqrt(1-alphas_bar[t]))+torch.sqrt(betas[t])*z
    
    x_t = x_t_minus_one

4、结果

因为设备有限,训练网红人脸数据,测试时网络生成的结果如下:这是在一张3080ti上训练得到的结果

巴斯扩散模型python 巴斯扩散模型推导_计算机视觉_71

5、网络模型

模型使用UNet,并具有第t扩散步的位置编码信息。

6、其他

github:https://github.com/HibikiJie/Diffusion-Models

权重
链接:https://pan.baidu.com/s/19PuZr6duixJaSU1kvmn8Vg
码:yhR9