扩散模型DDPM的解读

写在前面

  • 本文基于苏剑林老师的文章,在此基础上加了一点点自己的理解,在公式的推导上步骤进行了补全(苏老师写的已经很好了,只不过我把步骤写全了,让零基础的人更能看懂)。
  • 苏老师的文章

1.将生成模型类比为建楼和拆楼

  • 想要做一个像GAN那样的生成模型,它实际上是将一个随机噪声 z z z变换成一个数据样本 x x x的过程。

1.1 类比

  • 随机噪声 z z z类比为砖瓦水泥样本数据 x x x类比为高楼大厦;
  • z z z x x x的变换,相当于 砖瓦水泥建设高楼大厦;
  • 生成模型就是一支用原材料建设高楼大厦的施工队,过程很难;

1.2 换种思路:先拆楼

  • 所以我们换种思路建楼难,我们就先不建楼,改成拆楼,考虑将高楼大厦一步步地拆为砖瓦水泥,这样我们就知道怎么建楼;
  • 拆楼的过程:设 x 0 x_0 x0建好的高楼大厦数据样本), x T x_T xT拆好的砖瓦水泥随机噪声),假设“拆楼”需要 T T T步,整个过程可以表示为 x = x 0 → x 1 → x 2 → . . . → x T − 1 → x T = z (1) x=x_0\rightarrow x_1\rightarrow x_2\rightarrow...\rightarrow x_{T-1}\rightarrow x_T=z \tag{1} x=x0x1x2...xT1xT=z(1)

1.3 建楼的难点

  • 建高楼大厦的难度在于,从原材料 x T x_T xT最终高楼大厦 x 0 x_0 x0跨度过大,普通人很难理解 x T x_T xT是怎么一下子变成 x 0 x_0 x0的,先记住我们的目标生成 x 0 x_0 x0这个高楼大厦。
  • 当我们知道拆楼的过程 x 1 , x 2 , . . . , x T x_1,x_2,...,x_T x1,x2,...,xT后,就可以知道 x t − 1 → x t x_{t-1}\rightarrow x_t xt1xt( t − 1 t-1 t1步到 t t t步时)代表着拆楼的一步
  • 反过来 x t → x t − 1 x_{t}\rightarrow x_{t-1} xtxt1就是建楼的一步
  • 如果能学会两者之间的变换关系 x t − 1 = μ ( x t ) x_{t-1}=\mu(x_t) xt1=μ(xt)这里是建楼 x t → x t − 1 x_{t}\rightarrow x_{t-1} xtxt1),那么 z = x T z=x_T z=xT开始反复执行 x T − 1 = μ ( x T ) x_{T-1}=\mu(x_T) xT1=μ(xT) x T − 2 = μ ( x T − 1 ) x_{T-2}=\mu(x_{T-1}) xT2=μ(xT1) . . . ... ...最终就将高楼大厦造出来了 x 0 x_0 x0

2. 回到拆楼,怎么拆楼?

  • DDPM做生成模型的过程,其实跟上述“拆楼-建楼”的类比是完全一致的,它也是先反过来构建一个从数据样本渐变到随机噪声的过程,然后再考虑其逆变换,通过反复执行逆变换来完成数据样本的生成。

2.1 拆楼的过程

  • DDPM将“拆楼”的过程建模 x t = α t x t − 1 + β t ε t , ( ε t ∼ N ( 0 , I ) ) (2) x_t=\alpha_t x_{t-1}+\beta_t \varepsilon_t, (\varepsilon_t \sim N(0, I)) \tag{2} xt=αtxt1+βtεt,(εtN(0,I))(2)
    • α t , β t > 0 \alpha_t,\beta_t>0 αt,βt>0 α t 2 + β t 2 = 1 \alpha_t^2+\beta_t^2=1 αt2+βt2=1;(优化了一下原论文的参数)
    • β t \beta_t βt非常接近0代表着单步拆楼中对原来楼体的破坏程度
    • 噪声 ε t \varepsilon_t εt的引入代表着对原始信号的一种破坏,也就是原材料;
    • 每一步拆楼都将 x t − 1 x_{t-1} xt1拆分成 α t x t − 1 \alpha_tx_{t-1} αtxt1楼体+ β t ε t \beta_t\varepsilon_t βtεt原料这样想:拆楼,都是在原楼体上拆,这样,原楼体还剩,a*原楼体(a肯定小于1),还有一堆拆下来的砖块等原料。
  • 反复执行这个拆楼步骤
    x t = α t x t − 1 + β t ε t = α t ( α t − 1 x t − 2 + β t − 1 ε t − 1 ) = ⋅ ⋅ ⋅ = ( α t ⋅ ⋅ ⋅ α 1 ) x 0 + ( α t ⋅ ⋅ ⋅ α 2 ) β 1 ε 1 + ( α t ⋅ ⋅ ⋅ α 3 ) β 2 ε 2 + ⋅ ⋅ ⋅ + α t β t − 1 ε t − 1 + β t ε t (3) \begin{aligned} x_t &=\alpha_t x_{t-1}+\beta_t \varepsilon_t \\ &=\alpha_t(\alpha_{t-1} x_{t-2}+\beta_{t-1} \varepsilon_{t-1})\\ &=···\\ &=(\alpha_t···\alpha_1)x_0+(\alpha_t···\alpha_2)\beta_1\varepsilon_1+(\alpha_t···\alpha_3)\beta_2\varepsilon_2+···+\alpha_t\beta_{t-1}\varepsilon_{t-1}+\beta_{t}\varepsilon_{t} \tag{3} \end{aligned} xt=αtxt1+βtεt=αt(αt1xt2+βt1εt1)==(αtα1)x0+(αtα2)β1ε1+(αtα3)β2ε2++αtβt1εt1+βtεt(3)
    • 第二项到最后 ( α t ⋅ ⋅ ⋅ α 2 ) β 1 ε 1 + ( α t ⋅ ⋅ ⋅ α 3 ) β 2 ε 2 + ⋅ ⋅ ⋅ + α t β t − 1 ε t − 1 + β t ε t (\alpha_t···\alpha_2)\beta_1\varepsilon_1+(\alpha_t···\alpha_3)\beta_2\varepsilon_2+···+\alpha_t\beta_{t-1}\varepsilon_{t-1}+\beta_{t}\varepsilon_{t} (αtα2)β1ε1+(αtα3)β2ε2++αtβt1εt1+βtεt)就是多个独立的正态噪声之和
    • 根据正态分布的叠加性
      • 如: ( α t ⋅ ⋅ ⋅ α 2 ) β 1 ε 1 ∼ N ( 0 , ( α t ⋅ ⋅ ⋅ α 2 ) 2 β 1 2 ⋅ I ) (\alpha_t···\alpha_2)\beta_1\varepsilon_1 \sim N\left(0,(\alpha_t···\alpha_2)^2\beta_1^2·I \right) (αtα2)β1ε1N(0,(αtα2)2β12I)
      • 所以都是均值为0,方差为 ( α t ⋅ ⋅ ⋅ α 2 ) 2 β 1 2 , ( α t ⋅ ⋅ ⋅ α 3 ) 2 β 2 2 , . . . , α t 2 β t − 1 2 , β t 2 (\alpha_t···\alpha_2)^2\beta_1^2,(\alpha_t···\alpha_3)^2\beta_2^2,...,\alpha_t^2\beta_{t-1}^2,\beta_{t}^2 (αtα2)2β12,(αtα3)2β22,...,αt2βt12,βt2的正态分布
      • 所有噪声和叠加,就是均值为0,方差为 ( α t ⋅ ⋅ ⋅ α 2 ) 2 β 1 2 + ( α t ⋅ ⋅ ⋅ α 3 ) 2 β 2 2 + . . . + α t 2 β t − 1 2 + β t 2 (\alpha_t···\alpha_2)^2\beta_1^2+(\alpha_t···\alpha_3)^2\beta_2^2+...+\alpha_t^2\beta_{t-1}^2+\beta_{t}^2 (αtα2)2β12+(αtα3)2β22+...+αt2βt12+βt2的正态分布(这里很容易得出,可以去看一下(常数*一个随机变量)的方差怎么算的,其实就是常数的平方*随机变量的方差)。
      • α t 2 + β t 2 = 1 \alpha_t^2+\beta_t^2=1 αt2+βt2=1进行恒等变换(就是所有 β \beta β换成 α \alpha α)就会得,方差为: 1 − ( α t ⋅ ⋅ ⋅ α 1 ) 2 1-(\alpha_t···\alpha_1)^2 1(αt
<think>好的,用户想了解扩散模型DDPM的实现和解释。首先,我需要回忆一下DDPM的基本概念。扩散模型主要包括正向过程和反向过程,正向过程逐步添加噪声,反向过程学习去噪。用户可能对这两个过程的具体实现感兴趣。 接下来,我需要考虑如何用中文清晰解释这些概念。根据用户提供的引用[2],生成模型的目标是建模复杂数据分布,并通过简单分布进行采样。这可能涉及到正向过程如何将数据逐渐变为噪声,反向过程如何从噪声恢复数据。 用户还提到实现方法,可能需要代码示例。我需要确保代码正确,使用PyTorch框架,并遵循用户对LaTeX格式的要求,例如数学公式用$...$或$$...$$。比如,正向过程的公式应该是: $$q(x_t|x_{t-1}) = \mathcal{N}(x_t; \sqrt{1-\beta_t}x_{t-1}, \beta_t\mathbf{I})$$ 然后,反向过程需要参数化网络来预测噪声,损失函数可能是MSE。代码部分要展示如何定义噪声调度、UNet模型和前向传播过程。 用户可能对如何训练模型和采样过程有疑问,所以需要详细解释训练循环和采样步骤。此外,引用[1]提到的采样步骤可能涉及到反向去噪的迭代过程,这部分需要结合引用内容。 最后,生成相关问题时要覆盖原理、数学、优化和应用等方面,确保问题有针对性,帮助用户深入理解。比如,损失函数的设计、与VAE的区别、优化方法等。 需要检查所有数学表达式是否符合格式要求,代码是否正确缩进,引用标识是否正确添加。确保回答结构清晰,分点解释,并自然融入引用内容。</think>### 扩散模型DDPM详解与实现 扩散模型(Denoising Diffusion Probabilistic Models, DDPM)通过逐步加噪与去噪过程实现数据生成,核心包含**正向扩散过程**和**反向去噪过程**[^2]。 #### 1. 核心原理 - **正向扩散过程**:将数据$x_0$通过$T$步逐渐添加高斯噪声,得到$x_T \sim \mathcal{N}(0,\mathbf{I})$: $$q(x_t|x_{t-1}) = \mathcal{N}(x_t; \sqrt{1-\beta_t}x_{t-1}, \beta_t\mathbf{I})$$ 其中$\beta_t$为噪声调度参数,控制噪声添加速度[^1]。 - **反向去噪过程**:通过神经网络学习从$x_t$恢复$x_{t-1}$: $$p_\theta(x_{t-1}|x_t) = \mathcal{N}(x_{t-1}; \mu_\theta(x_t,t), \Sigma_\theta(x_t,t))$$ #### 2. 关键实现步骤 ```python import torch import torch.nn as nn class UNet(nn.Module): def __init__(self): super().__init__() # 定义包含时间嵌入的UNet结构 self.time_embed = nn.Embedding(1000, 64) self.conv1 = nn.Conv2d(3, 64, 3, padding=1) # 添加下采样和上采样层... def forward_diffusion(x0, t, beta): """正向扩散过程""" sqrt_alpha = torch.sqrt(1 - beta[t]) noise = torch.randn_like(x0) xt = sqrt_alpha * x0 + torch.sqrt(beta[t]) * noise return xt, noise # 噪声调度设置(线性/余弦) T = 1000 beta = torch.linspace(1e-4, 0.02, T) ``` #### 3. 训练与采样 - **训练目标**:最小化预测噪声的MSE损失: $$\mathcal{L} = \mathbb{E}_{t,x_0,\epsilon}\left[\|\epsilon - \epsilon_\theta(x_t,t)\|^2\right]$$ - **采样过程**:从$x_T \sim \mathcal{N}(0,1)$开始迭代去噪: $$x_{t-1} = \frac{1}{\sqrt{\alpha_t}}(x_t - \frac{\beta_t}{\sqrt{1-\bar{\alpha}_t}}\epsilon_\theta(x_t,t)) + \sigma_t z$$ #### 4. 代码实现要点 ```python def train_step(model, x0, beta): t = torch.randint(0, len(beta), (x0.size(0),)) xt, noise = forward_diffusion(x0, t, beta) pred_noise = model(xt, t) loss = F.mse_loss(pred_noise, noise) return loss def sample(model, shape, beta): x = torch.randn(shape) for t in reversed(range(T)): x = denoise_step(model, x, t, beta) return x ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值