【论文速读】DDPM:Denoising Diffusion Probabilistic Models
DDPM前向过程、反向过程及Predicter
图片来自李宏毅老师视频
论文给出的伪代码
训练部分只有5梯度下降公式比较难理解:
上文中我们已知我们预测的是noise( ϵ \epsilon ϵ), ϵ \epsilon ϵ - ϵ θ ( x ) \epsilon_\theta(x) ϵθ(x) 其实就是真实值-预测值。其中我们的输入应该是 x T = x t − 1 + ϵ x_T = x_{t-1}+\epsilon xT=xt−1+ϵ 这个操作我们要循环T次才能得到结果 x T x_T xT,如下图,想要得到最后一次的结果,通过简化公式,一步就可以得到,和论文给出的公式一致。
其中 α ‾ t \overline{\alpha}_t αt是给定好的一组序列, { α ‾ 0 . . . α ‾ T } \{\overline{\alpha}_0 ... \overline{\alpha}_T\} {α0...αT},T长度通常设置为1000。
看懂训练部分公式,预测部分的公式就很简单了(预测部分常用DDIM方法,只执行几十步就可以完成一张不错的图):
简化后: x t − 1 x_{t-1} xt−1 = x t x_t xt - ϵ θ ( x ) \epsilon_\theta(x) ϵθ(x) ,因为 α ‾ \overline{\alpha} α是一个常量可以忽略。为什么要再加一个噪音暂时没懂
α ‾ t \overline{\alpha}_t αt,生成方式如下代码:( β \beta β为前向加噪权重)
betas = torch.Tensor(make_beta_schedule(schedule="linear", n_timestep=n_timestep)
)
# [0.9999, 0.9994, 0.9985, 0.9971, 0.9953, 0.9931, 0.9905, 0.9874, 0.9839,0.9800]
alphas = 1.0 - betasdef make_beta_schedule(schedule, n_timestep, linear_start=1e-4, linear_end=2e-2, cosine_s=8e-3
):if schedule == "linear":betas = (torch.linspace(linear_start ** 0.5, linear_end ** 0.5, n_timestep, dtype=torch.float64)** 2)elif schedule == "cosine":timesteps = (torch.arange(n_timestep + 1, dtype=torch.float64) / n_timestep + cosine_s)alphas = timesteps / (1 + cosine_s) * np.pi / 2alphas = torch.cos(alphas).pow(2)alphas = alphas / alphas[0]betas = 1 - alphas[1:] / alphas[:-1]betas = np.clip(betas, a_min=0, a_max=0.999)elif schedule == "sqrt_linear":betas = torch.linspace(linear_start, linear_end, n_timestep, dtype=torch.float64)elif schedule == "sqrt":betas = (torch.linspace(linear_start, linear_end, n_timestep, dtype=torch.float64)** 0.5)else:raise ValueError(f"schedule '{schedule}' unknown.")return betas.numpy()