『扩散模型』一篇文章入门随机微分方程SDE

随机微分方程SDE

笔者建议,学完DDPM再来看SDE的作用和推导过程

标准布朗运动

在学习随机微分方程之前,我们先来看一下什么是标准布朗运动
假设有一个一维的直线,有个小人从原点出发,每次随机地选择向左走1格或者向右走1格,且向左走和向右走的两个选项,被选择的概率相等 → \rightarrow S t S_t St代表小人离原点的距离, t t t代表代表选择的次数,如果选择的次数越多,那么 S t S_t St将会逐渐服从一个均值为0、方差为 t t t的正态分布
布朗运动 W ( t ) W(t) W(t)是期望为0、方差为 t t t的正态分布 ⇔ \Leftrightarrow W t ∼ N ( 0 , t ) W_t\sim \mathcal{N}(0,t) WtN(0,t) ⇒ \Rightarrow W t + Δ t − W t ∼ N ( 0 , Δ t ) W_{t+\Delta t}-W_t\sim \mathcal{N}(0,\Delta t) Wt+ΔtWtN(0,Δt),当 Δ t → 0 \Delta t\rightarrow 0 Δt0时, d w = d t ε dw=\sqrt{dt}\varepsilon dw=dt ε(重参数技巧)

SDE加噪

在DDPM中,扩散过程被划分为固定的T步 ⇒ \Rightarrow DDPM=拆楼+建楼 ⇒ \Rightarrow “拆楼”和“建楼”都被事先划分为了T步,这个划分有着相当大的人为性。事实上,真实的“拆”、“建”过程应该是没有刻意划分的步骤 ⇒ \Rightarrow 可以将它们理解为一个在时间上连续的变换过程,可以用随机微分方程(Stochastic Differential Equation,SDE)来描述,即 d x = f t ( x ) d t + g t d w t d\boldsymbol{x}=\boldsymbol{f}_t(\boldsymbol{x})dt+g_td\boldsymbol{w_t} dx=ft(x)dt+gtdwt,其中 f t ( x t ) f_t(x_t) ft(xt)是漂移项,描述数据的确定性演化 g t g_t gt是扩散项,描述的是噪声的扩散程度 d w t dw_t dwt是维纳运动(布朗运动)的微小增量,表示随机波动
随机微分方程: d x = dx= dx=确定的变化 + + +随机的变化,其中随机的变化代表着随机性
随机微分方程描述了系统从 t t t时刻到 t + Δ t t+\Delta t t+Δt时刻的变化
我们可以将随机微分方程看成是 x t + Δ t − x t = f t ( x t ) Δ t + g t Δ t ε , ε ∼ N ( 0 , I ) \boldsymbol{x}_{t+\Delta t}-\boldsymbol{x}_t=\boldsymbol{f}_t(\boldsymbol{x}_t)\Delta t+g_t\sqrt{\Delta t}\boldsymbol{\varepsilon},\quad\boldsymbol{\varepsilon}\sim\mathcal{N}(\boldsymbol{0},\boldsymbol{I}) xt+Δtxt=ft(xt)Δt+gtΔt ε,εN(0,I) Δ t → 0 \Delta t\rightarrow 0 Δt0时的极限 ⇒ \Rightarrow 如果建楼要1天,那么拆楼就是 x x x t = 0 t=0 t=0 t = 1 t=1 t=1时刻的变化
越小的步数 Δ t \Delta t Δt意味着对原始噪声越好的近似,如果 Δ t = 0.001 \Delta t=0.001 Δt=0.001,对应着 T = 1000 T=1000 T=1000;如果 Δ t = 0.01 \Delta t=0.01 Δt=0.01,则对应 T = 100 T=100 T=100(总时间步数 T T T是模拟的总时间跨度被步长 Δ t \Delta t Δt划分的次数 T = t max ⁡ Δ t T=\frac{t_{\max}}{\Delta t} T=Δttmax ⇒ \Rightarrow 引入SDE的本质好处是将理论分析和代码实现分离开来
DDPM的加噪过程本质上是一个SDE,而SDE本质上描述的是微小时间变化下系统状态的变化

  • DDPM的加噪: x t + 1 = 1 − β t x t + β t ϵ x_{t+1}=\sqrt{1-\beta_t}x_t+\sqrt{\beta_t}\epsilon xt+1=1βt xt+βt ϵ
  • SDE的加噪: d x = f t ( x ) d t + g t d w t d\boldsymbol{x}=\boldsymbol{f}_t(\boldsymbol{x})dt+g_td\boldsymbol{w_t} dx=ft(x)dt+gtdwt

在这里,笔者介绍一下将DDPM加噪公式映射到SDE加噪公式的推导过程:

  1. 重写DDPM加噪公式: x t + 1 − x t = ( 1 − β t − 1 ) x t + β t ϵ x_{t+1}-x_t=(\sqrt{1-\beta_t}-1)x_t+\sqrt{\beta_t}\epsilon xt+1xt=(1βt 1)xt+βt ϵ ⇒ \Rightarrow 1 − β t ≈ 1 − β t 2 \sqrt{1-\beta_t}\approx1-\frac{\beta_t}2 1βt 12βt ⇒ \Rightarrow 将DDPM加噪公式重新表示为一个确定项和随机噪声项的和: x t + 1 − x t ≈ − β t 2 x t + β t ϵ x_{t+1}-x_{t}\approx-\frac{\beta_{t}}{2}x_{t}+\sqrt{\beta_{t}}\epsilon xt+1xt2βtxt+βt ϵ
    在这里,使用泰勒展开得到 1 − β t ≈ 1 − β t 2 \sqrt{1-\beta_t}\approx1-\frac{\beta_t}2 1βt 12βt
    先来介绍一下泰勒展开:如果 f ( x ) f(x) f(x) x = a x=a x=a处是可微的,则它的泰勒展开可以写为 f ( x ) ≈ f ( a ) + f ′ ( a ) ( x − a ) + f ′ ′ ( a ) 2 ! ( x − a ) 2 + … f(x)\approx f(a)+f'(a)(x-a)+\frac{f''(a)}{2!}(x-a)^2+\ldots f(x)f(a)+f(a)(xa)+2!f′′(a)(xa)2+,其中 f ′ ( a ) f'(a) f(a) f ′ ′ ( a ) f''(a) f′′(a)分别是 f ( x ) f(x) f(x) a a a处的一阶导数和二阶导数;在泰勒展开中,若函数依赖多个变量,需要对每个变量分别进行展开
    f ( β t ) = 1 − β t f(\beta_t)=\sqrt{1-\beta_t} f(βt)=1βt β t = 0 \beta_t=0 βt=0处展开 ⇒ \Rightarrow 零阶项: f ( 0 ) = 1 − 0 = 1 f(0)=\sqrt{1-0}=1 f(0)=10 =1;一阶导数: f ′ ( β t ) = d d β t 1 − β t = − 1 2 1 − β t f'(\beta_t)=\frac{d}{d\beta_t}\sqrt{1-\beta_t}=\frac{-1}{2\sqrt{1-\beta_t}} f(βt)=dβtd1βt =21βt 1,在 β t = 0 \beta_t=0 βt=0 f ′ ( 0 ) = − 1 2 1 − 0 = − 1 2 f'(0)=\frac{-1}{2\sqrt{1-0}}=-\frac{1}{2} f(0)=<
### 基于随机微分方程的扩散生成模型介绍 #### 定义与背景 基于随机微分方程(SDE)的扩散生成模型是一种强大的概率生成模型,它通过逆向求解SDE来学习数据分布。这类模型利用了分数匹配(score matching),即估计给定噪声数据的概率密度函数梯度,从而构建复杂的多维分布。 #### 统一框架下的方法论 透过SDE视角泛化的分数匹配技术提供了一个统一的方法论框架[^2]。此框架不仅能够处理连续时间过程中的渐变变化,而且可以灵活适应不同的前向和反向转换策略。新提出的采样算法增强了这些模型的表现力,在图像合成等领域展现了优越性能。 #### 实现流程概述 具体来说,该类模型通常涉及两个主要阶段: - **加噪过程**:从初始干净样本出发逐步引入高斯白噪音直至达到预定程度; - **去噪重建**:采用神经网络预测每一步骤对应的条件得分函数,并据此指导恢复原始信号的过程。 这一双向机制允许模型有效地捕捉并重现复杂的数据结构特征。 ```python import torch from torch import nn, optim import numpy as np class ScoreNetwork(nn.Module): def __init__(self, input_dim=784, hidden_dims=[1024]*3): super().__init__() layers = [] dims = [input_dim] + hidden_dims + [input_dim] for i in range(len(dims)-1): layers.append(nn.Linear(dims[i], dims[i+1])) if i != len(dims)-2: layers.extend([nn.ReLU(), nn.Dropout(p=0.1)]) self.net = nn.Sequential(*layers) def forward(self, x_tilde, t): # Concatenate time step to the noisy data xt = torch.cat((x_tilde.view(-1),t.unsqueeze(dim=-1)), dim=-1) score = self.net(xt).view_as(x_tilde) return score def train_score_network(model, optimizer, dataloader, n_epochs=50): criterion = lambda pred_scores,true_scores: ((pred_scores - true_scores)**2).mean() for epoch in range(n_epochs): running_loss = 0. for batch_idx,(data,) in enumerate(dataloader): noise_level = torch.randn_like(data)*np.sqrt(epoch/n_epochs*0.1+.9) noised_data = data + noise_level scores_true = (-noise_level / (epoch/n_epochs*.1+.9)).to(device=data.device) predicted_scores = model(noised_data.to(device=data.device), torch.tensor([epoch/n_epochs]).float().to(device=data.device)) loss = criterion(predicted_scores,scores_true) optimizer.zero_grad();loss.backward();optimizer.step(); running_loss += loss.item()*len(batch_idx)/len(dataloader.dataset) print(f'Epoch {epoch}/{n_epochs}, Loss={running_loss:.4f}') ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值