写在前面
强烈推荐这个:
https://huggingface.co/datasets/HuggingFace-CN-community diffusion 教程
扩散模型是如何工作的:从零开始的数学原理
以下内容参考自:
Probabilistic Diffusion Model概率扩散模型理论与完整PyTorch代码详细解读
知乎:diffusion model 最近在图像生成领域大红大紫,如何看待它的风头开始超过 GAN ?
diffusion 简单demo
扩散模型之DDPM
Diffusion model 原理剖析
张振虎-扩散概率模型
生成扩散模型漫谈(一):DDPM = 拆楼 + 建楼
核心公式和逻辑
优化目标:
然后:
然后:
核心公式:
训练阶段
实际上是根据加噪后的图 和时间步 t 去预测噪声
q_x
计算公式,后面会用到:
推理
代码
import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets import make_s_curve, make_swiss_roll
from PIL import Image
import torch
import io
# get data
# s_curve, _ = make_s_curve(10**4 , noise=0.1)
# s_curve = s_curve[:, [0, 2]] / 10.0
swiss_roll, _ = make_swiss_roll(10**4,noise=0.1)
s_curve = swiss_roll[:, [0, 2]]/10.0
print('shape of moons: ', np.shape(s_curve))
data = s_curve.T
fix, ax = plt.subplots()
ax.scatter(*data, color='red', edgecolors='white', alpha=0.5)
ax.axis('off')
# plt.show()
plt.savefig('./s_curve.png')
dataset = torch.Tensor(s_curve).float()
# set params
num_steps = 100
betas = torch.linspace(-6, 6, num_steps) # # 逐渐递增
betas = torch.sigmoid(betas) * (0.5e-2 - 1e-5) + 1e-5 # β0,β1,...,βt
print('beta: ', betas)
alphas = 1 - betas
alphas_pro = torch.cumprod(alphas, 0) # αt^ = αt的累乘
# αt^往右平移一位, 原第t步的值维第t-1步的值, 第0步补1
alphas_pro_p = torch.cat([torch.tensor([1]).float(), alphas_pro[:-1]], 0) # p表示previous, 即 αt-1^
alphas_bar_sqrt = torch.sqrt(alphas_pro) # αt^ 开根号
one_minus_alphas_bar_log = torch.log(1 - alphas_pro) # log (1 - αt^)
one_minus_alphas_bar_sqrt = torch.sqrt(1 - alphas_pro) # 根号下(1-αt^)
assert alphas.shape == alphas_pro.shape == alphas_pro_p.shape == alphas_bar_sqrt.shape == one_minus_alphas_bar_log.shape == one_minus_alphas_bar_sqrt.shape
print('beta: shape ', betas