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 - betas
def 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 / 2
alphas = 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()


4729

被折叠的 条评论
为什么被折叠?



