文章目录
- Diffusion Model 基础
- 生成模型
- DDPM概述
- 向前扩散过程
- 前向扩散的逐步过程
- 前向扩散的整体过程
- 反向去噪过程
- 网络结构
- 训练和推理过程
- 训练过程
- 推理过程
- 优化目标
- 详细数学推导
- 数学基础
- 向前扩散过程
- 反向去噪过程
- Stable Diffusion
- 组成结构
- 运行流程
- 网络结构
- VAE 模型
- 文本编码器
- 噪音预测器
- Unet 模型
- 训练过程和损失函数
- 参考
Diffusion Model 基础
生成模型
常见的生成模型有:
- GAN
- VAE
- Flow-based
与 VAE 或Flow-based 模型不同,扩散模型是通过固定的过程学习的,latent variable 具有高维度(与原始数据相同)。
文生图模型的基本架构如下:
- 文本编码器(
Text Encoder
)用于编码文本的输入 - 生成模型 (
Generation Model
)输入文字和杂讯,生成一个中间产物(这个中间产物可以是人看得懂的一个压缩图片,也可以是噪音) - 解码器 (
Decoder
) 解码器,输入中间产物,得到最终的输出的图片。
通常而言,上述的三个模型是分开训练的,最后组合到一起。
- 例如 Stable Diffusion
- DALL-E
- Imagen
衡量图像生成质量的指标
- FID
将生成的图片和真是的图片都输入到预训练好的CNN模型中,然后计算输出高斯分布的Frechet的距离。其值越小越好。
- CLIP score
将生成的图片和输入的文本提示,分别送入Image encoder 和text encoder ,计算二者输出的距离。如果图像文本匹配,则距离越近越好。如果不匹配,则其距离越远越好。CLIP score的得分越大越好。
DDPM概述
- 基本思想
Denoising Diffusion Probabilistic Models (DDPM)
受非平衡统计物理启发[1],是通过一个迭代的向前扩散过程 ,系统地、缓慢地破坏数据分布中的结构。然后,我们学习一个逆扩散过程,将数据中的结构恢复,从而产生一个高度灵活且易于处理的数据生成模型。
💡 原文中作者对于基本思想的描述:“The essential idea, inspired by non-equilibrium statistical physics [1], is to systematically and slowly
destroy structure
in a data distribution* through an iterative forward diffusion process. We then learn a reverse diffusion process thatrestores structure
in data, yielding a highly flexible and tractable generative model of the data.”
- 核心步骤
基于上述思想,Denoising diffusion 模型包括两个过程:
向前扩散过程 (Forward Diffusion)
: 逐渐向输入添加噪声反向去噪过程 (Reverse Denoising)
: 学习通过去噪生成数据
向前扩散过程
前向扩散的逐步过程
首先,我们先来介绍一下如何破坏数据分布。
如果我们取任何一幅图像(上图a),它具有某种非随机分布。我们不知道这个分布,但我们的目标是破坏它,我们可以通过向其添加噪声来实现。在这个过程的最后,我们应该得到类似于纯噪声的噪声(上图b)。
前向扩散过程的每一步被定义为 q ( x t ∣ x t − 1 ) = N ( x t , 1 − β t x t − 1 , β t I ) q(x_t|x_{t-1})= \mathcal{N}\left(x_t, \sqrt{1-\beta_t} x_{t-1}, \beta_t I\right) q(xt∣xt−1)=N(xt,1−βtxt−1,βtI)
其中 q q q是前向扩散过程, x t x_t xt是第 t t t步前向过程的输出(自然地, x t − 1 x_{t-1} xt−1是第 t t t步的输入)。 N \mathcal{N} N是一个正态分布, 1 − β t x t − 1 \sqrt{1-\beta_t} x_{t-1} 1−βtxt−1是均值, β t I \beta_t I βtI定义了一个方差。
调度 (Schedule)
β t \beta_t βt被称为调度(schedule)
,其值范围从0到1不等。通常将值保持在较低水平,以防止方差爆炸。
- 线性调度(Linear Schedule)
DDPM论文 [2] 使用了一个线性调度,因此输出看起来如下图:
在线性调度的情况下, β t \beta_t βt从0.0001线性增加到0.02, 均值和方差也随着时间步线性变化(如下图)。
- 余弦调度(Cosine Schedule)
OpenAI的研究人员在他们的2021年论文中 [3] 发现使用线性调度并不那么高效。因此提出了余弦调度(下图)。这种改进使得步骤数减少到50步。
前向扩散的整体过程
使用前向扩散过程向图像添加噪声将会很慢。训练过程不使用与前向过程一致的示例,而是使用来自任意时间步 t 的样本。这意味着在每个训练步骤中,我们需要通过 t 步来生成 1 个训练样本。
q ( x 1 : T ∣ x 0 ) : = ∏ t = 1 T q ( x t ∣ x t − 1 ) q\left(x_{1: T} \mid x_0\right):=\prod_{t=1}^T q\left(x_t \mid x_{t-1}\right) q(x1:T∣x0):=t=1∏Tq(xt∣xt−1)
接下来,我们对上式进行逐步分解:
q t ( q t − 1 ( q t − 2 ( q t − 3 ( ⋯ q 1 ( x 0 ) ) ) ) ) q_t\left(q_{t-1}\left(q_{t-2}\left(q_{t-3}\left(\cdots q_1\left(x_0\right)\right)\right)\right)\right) qt(qt−1(qt−2(qt−3(⋯q1(x0)))))
t 1 t_1 t1时刻
q ( x 1 ∣ x 0 ) = N ( x 1 , 1 − β 1 x 0 , β 1 I ) q\left(x_1 \mid x_0\right)=\mathcal{N}\left(x_1, \sqrt{1-\beta_1} x_0, \beta_1 I\right) q(x1∣x0)=N(x1,1−β1x0,β1I)
t 2 t_2 t2时刻
q ( x 2 ∣ x 1 ) = N ( x 2 , 1 − β 2 x 1 , β 2 I ) q\left(x_2 \mid x_1\right)=\mathcal{N}\left(x_2, \sqrt{1-\beta_2} x_1, \beta_2 I\right) q(x2∣x1)=N(x2,1−β2x1,β2I)
从上面的公式可以看到,只有均值是依赖于上一步的输出,方差对于任意一步都是已知的(因为 β \beta β 对于每一个时间步都是已知的)。
因此,引入下面两个记号:
α t = 1 − β t α ˉ t : = ∏ s = 1 t a s \begin{aligned} \alpha_t & =1-\beta_t \\ \bar{\alpha}_t & :=\prod_{s=1}^t a_s \end{aligned} αtαˉt=1−βt:=s=1∏tas
代入上述记号,每一步的加噪公式变为:
q ( x 1 ∣ x 0 ) = N ( x 1 , α 1 x 0 , ( 1 − α 1 ) I ) q\left(x_1 \mid x_0\right)=\mathcal{N}\left(x_1, \sqrt{\alpha_1} x_0,\left(1-\alpha_1\right) I\right) q(x1∣x0)=N(x1,α1x0,(1−α1)I)
q ( x 2 ∣ x 1 ) = N ( x 2 , α 2 x 1 , ( 1 − α 2 ) I ) q\left(x_2 \mid x_1\right)=\mathcal{N}\left(x_2, \sqrt{\alpha_2} x_1,\left(1-\alpha_2\right) I\right) q(x2∣x1)=N(x2,α2x1,(1−α2)I)
整个过程的均值计算如下:
μ t = α t x t − 1 = α t ∗ α t − 1 x t − 2 = α t α t − 1 x t − 2 = α t α t − 1 ∗ α t − 2 x t − 3 = α t α t − 1 α t − 2 x t − 3 = α t α t − 1 α t − 2 ⋯ ∗ α 1 x 0 = α t α t − 1 α t − 2 ⋯ α 1 x 0 = α ˉ t x 0 \begin{gathered} \mu_t=\sqrt{\alpha_t} x_{t-1} \\ =\sqrt{\alpha_t} * \sqrt{\alpha_{t-1}} x_{t-2}=\sqrt{\alpha_t \alpha_{t-1}} x_{t-2} \\ =\sqrt{\alpha_t \alpha_{t-1}} * \sqrt{\alpha_{t-2}} x_{t-3}=\sqrt{\alpha_t \alpha_{t-1} \alpha_{t-2}} x_{t-3} \\ =\sqrt{\alpha_t \alpha_{t-1} \alpha_{t-2} \cdots} * \sqrt{\alpha_1} x_0=\sqrt{\alpha_t \alpha_{t-1} \alpha_{t-2} \cdots \alpha_1} x_0 \\ =\sqrt{\bar{\alpha}_t} x_0 \end{gathered} μt=αtxt−1=αt∗αt−1xt−2=αtαt−1xt−2=αtαt−1∗αt−2xt−3=αtαt−1αt−2xt−3=αtαt−1αt−2⋯∗α1x0=αtαt−1αt−2⋯α1x0=αˉtx0
最终可以写出从 0 到 t 的整个过程的公式:
q ( x t ∣ x 0 ) = N ( x t , α ˉ t x 0 , ( 1 − α ˉ t ) I ) q\left(x_t \mid x_0\right)=\mathcal{N}\left(x_t, \sqrt{\bar{\alpha}_t} x_0,\left(1-\bar{\alpha}_t\right) I\right) q(xt∣x0)=N(xt,αˉtx0,(1−αˉt)I)
然而上述的过程是无法计算的,需要对每一步前向步骤应用重参数化技巧: N ( μ , σ 2 ) = μ + σ ∗ ϵ \mathcal{N}\left(\mu, \sigma^2\right)=\mu+\sigma * \epsilon N(μ,σ2)=μ+σ∗ϵ, 其中 ϵ \epsilon ϵ来自于 N ( 0 , 1 ) \mathcal{N}(0,1) N(0,1)
q ( x t ∣ x t − 1 ) = N ( x t , 1 − β t x t − 1 , β t I ) = 1 − β t x t − 1 + β t ϵ \begin{gathered} q\left(x_t \mid x_{t-1}\right)=\mathcal{N}\left(x_t, \sqrt{1-\beta_t} x_{t-1}, \beta_t I\right) \\ =\sqrt{1-\beta_t} x_{t-1}+\sqrt{\beta_t} \epsilon \end{gathered} q(xt∣xt−1)=N(xt,1−βtxt−1,βtI)=1−βtxt−1+βtϵ
因为我们知道 t = 1.. T t=1..T t=1..T 的公式是什么,我们可以使用这个技巧来得到可计算的方程式。
q ( x t ∣ x t − 1 ) = N ( x t , 1 − β t x t − 1 , β t I ) = 1 − β t x t − 1 + β t ϵ \begin{gathered} q\left(x_t \mid x_{t-1}\right)=\mathcal{N}\left(x_t, \sqrt{1-\beta_t} x_{t-1}, \beta_t I\right) \\ =\sqrt{1-\beta_t} x_{t-1}+\sqrt{\beta_t} \epsilon \end{gathered} q(xt∣xt−1)=N(xt,1−βtxt−1,βtI)=1−βtxt−1+βtϵ
反向去噪过程
可视化步骤
数学推导
论文中定义的反向去噪的公式如下:
p θ ( x 0 : T ) : = p ( x T ) ∏ t = 1 T p θ ( x t − 1 ∣ x t ) p_\theta\left(x_{0: T}\right):=p\left(x_T\right) \prod_{t=1}^T p_\theta\left(x_{t-1} \mid x_t\right) pθ(x0:T):=p(xT)t=1∏Tpθ(xt−1∣xt)
其中
p θ ( x t − 1 ∣ x t ) = N ( x t − 1 , μ θ ( x t , t ) , ∑ θ ( x t , t ) ) p_\theta\left(x_{t-1} \mid x_t\right)=\mathcal{N}\left(x_{t-1}, \mu_\theta\left(x_t, t\right), \sum_\theta\left(x_t, t\right)\right) pθ(xt−1∣xt)=N(xt−1,μθ(xt,t),θ∑(xt,t))
扩散过程 p θ ( x 0 : T ) p_\theta\left(x_{0: T}\right) pθ(x0:T)是一个从 p ( x T ) p(x_T) p(xT)开始的高斯转换链 (chain of gaussian transitions
),使用一个扩散过程步骤的方程在 𝑇 次迭代中进行,即 p θ ( x t − 1 ∣ x t ) p_\theta\left(x_{t-1} \mid x_t\right) pθ(xt−1∣xt)。
N ( x t − 1 , μ θ ( x t , t ) , ∑ θ ( x t , t ) ) \mathcal{N}\left(x_{t-1}, \mu_\theta\left(x_t, t\right), \sum_\theta\left(x_t, t\right)\right) N(xt−1,μθ(xt,t),∑θ(xt,t)) 包含两个部分 :
- 第一个部分是均值 μ θ ( x t , t ) \mu_\theta\left(x_t, t\right) μθ(xt,t)
μ θ ( x t , t ) = 1 α t ( x t − 1 − α t 1 − α ˉ t ϵ θ ( x t , t ) ) \mu_\theta\left(x_t, t\right)=\frac{1}{\sqrt{\alpha_t}}\left(x_t-\frac{1-\alpha_t}{\sqrt{1-\bar{\alpha}_t}} \epsilon_\theta\left(x_t, t\right)\right) μθ(xt,t)=αt1(xt−1−αˉt1−αtϵθ(xt,t))
- 第二部分是方差 ∑ θ ( x t , t ) \sum_\theta\left(x_t, t\right) ∑θ(xt,t) (等于 σ t 2 I \sigma_t^2 I σt2I)
方差是不可训练的,但是依赖于时间变化,即 β T I \beta_TI βTI (这里的 β \beta β 和前向过程中的 β \beta β一致,都表示的是调度)
这里先不涉及具体的推导,只是简单介绍下流程,具体的推导可以参考论文中的Appendix A [2] 和Lilian Weng的博文[b.5]
这样,我们可以得到 x t − 1 x_{t-1} xt−1
x t − 1 = N ( x t − 1 , 1 α t ( x t − β t 1 − α ˉ t ϵ θ ( x t , t ) ) , β t ϵ ) x_{t-1}=\mathcal{N}\left(x_{t-1}, \frac{1}{\sqrt{\alpha_t}}\left(x_t-\frac{\beta_t}{\sqrt{1-\bar{\alpha}_t}} \epsilon_\theta\left(x_t, t\right)\right), \sqrt{\beta_t} \epsilon\right) xt−1=N(xt−1,αt1(xt−1−αˉtβtϵθ(xt,t)),βtϵ)
进一步的,我们计算给定时间步t时刻的输出:
x t − 1 = 1 a t ( x t − β t 1 − α ˉ ϵ θ ( x t , t ) ) + β t ϵ x_{t-1}=\frac{1}{\sqrt{a_t}}\left(x_t-\frac{\beta_t}{\sqrt{1-\bar{\alpha}}} \epsilon_\theta\left(x_t, t\right)\right)+\sqrt{\beta_t} \epsilon xt−1=at1(xt−1−αˉβtϵθ(xt,t))+βtϵ
其中 ϵ θ ( x t , t ) \epsilon_\theta\left(x_t, t\right) ϵθ(xt,t) 是模型的输出,即预测出的噪音。
网络结构
模型架构是修改后的 U-Net 架构 [4]。它非常简单,但随着对扩散模型的进一步改进(例如,Stabel Diffusion 增加了整个潜在层用于图像数据嵌入)。在这里,我们先只讨论Diffusion Model的最初版本
首先修改的Unet 架构,将基础的ResNetBlock替换成Self-Attention Block, 或者修改后的ResNet Block。
然后,为了防止信息丢失,添加跳跃连接(skip connection)
下一步是添加关于当前时间步 t 的信息。为此,我们使用正弦嵌入(sinusoidal embedding),该信息被添加到所有下采样和上采样块中。
为了使网络是条件化的(依赖于外部输入),我们添加了一个文本嵌入器。它将为给定的文本创建嵌入,并将输出向量添加到时间步嵌入中。
ResNet Block
ResNet Block的结构如下,被用于下采样和上采样块的一部分。
Downsample Block
下采样块是第一个不仅接收来自前一层的数据,还接收有关时间步长和提示的数据的块。该块具有2个输入,并且表现为 U-Net 架构中的标准下采样。它接收输入并将其下采样到下一层的大小。
它使用 MaxPool2d
层(核大小为2),将输入大小减半(64x64 -> 32x32)。之后,连接2个 ResNet
块。
嵌入经过 Sigmoid
线性单元处理,然后通过一个简单的Linear
层,以达到与 ResNet 块输出相同的形状。之后,两个张量相加,并发送到下一个块。
Self-Attention Block
所有的注意力块的结构都相同,所以将用第一个来描述所有的注意力块(就在第一个下采样之后)。
首先,它接收一个形状为 (128, 32, 32) 的下采样张量。
然后,对输入张量进行reshape: 压缩最后两个维度,然后翻转得到的张量((128,32,32) -> (128, 1024) -> (1024, 128))并通过层归一化,并将其用作所有 3 个输入张量(Q、K、V)
接着,输入到一个多头注意力(Multi-Head Attention, MHA),嵌入维度设置为 128,有 4 个注意力头。嵌入维度在注意力块之间变化(取决于输入长度),而头的数量保持不变。
在块内部,作者添加了两个跳跃连接,与自注意力输出组合。
第一个连接将reshape 后的输入添加到注意力层的输出中,并通过前向层(Normalization -> Linear -> GELU -> Linear)传递。
第二个连接从该层获取输出,并将其添加回注意力的输出。
最后,我们需要对张量进行reshape,最终输出的大小和输入大小一致((1024, 128) -> (128, 32, 32))。
Upsample block
使用一个简单的上采样层,缩放因子为2。
通过上采样层传递输入张量后,我们可以将其与残差连接(来自第一个 ResNet 块)连接起来。现在,它们两者的形状都是 (64, 64, 64)。
连接的张量然后通过 2 个 ResNet 块发送(与我们在下采样块中所做的相同)
第三个输入(再次与下采样块中相同)通过 SILU 和线性层发送,然后添加到第二个 ResNet 块的结果中。
整个架构以 Conv2d 层结束,该层使用核大小为 1,将我们的张量从 (64,64,64) 缩放回 (3, 64,64)。这是我们预测的噪声。
训练和推理过程
训练过程
上图是训练的伪代码:
- 数据集中采样一张图片 x 0 x_0 x0
- 采样一个时间步 t t t
- 从正态分布中采样一个噪音 ϵ \epsilon ϵ
- 前面我们定义过了如何在时间步t时刻,在无需迭代的情况下前向加噪 q ( x t ∣ x 0 ) = α ˉ t x 0 + 1 − α ˉ t ϵ q\left(x_t \mid x_0\right)=\sqrt{\bar{\alpha}_t} x_0+\sqrt{1-\bar{\alpha}_t} \epsilon q(xt∣x0)=αˉtx0+1−αˉtϵ, 然后用梯度下降去训练网络模型 ϵ θ \epsilon_\theta ϵθ ( ϵ θ \epsilon_\theta ϵθ是用于学习生成噪音的模型
Noise Predicter
)。 - 然后重复整个过程,直到模型最终收敛。
下图是训练过程的第5步的图解:
下图是Noise Predicter
的图解实例,它的输入有两个:一个是时间步t
, 另外一个是时间步t时刻对应的添加的噪音。
下图是实际的训练过程。input和ground truth和时间步 来自于前向加噪的过程。在实际应用中,Noise Predicter 还会有个文本提示的输入。
推理过程
推理
上图是推理的伪代码:
1) 先从标准高斯分布中采样一个噪音
2)从时间步 T T T开始,逐步推理前一步的输出 (输入t
时刻的带噪图片 x t x_t xt,生成t-1
时刻的带噪音图片 x t − 1 x_{t-1} xt−1)。
优化目标
对于真实的图片分布 P d a t a P_{data} Pdata中采样一些图片 x 1 , x 2 , x 3 . . . x^1,x^2,x^3... x1,x2,x3... 。然后从一个标准的高斯分布中采样一个噪音,通过生成网络(需要训练的参数集是 θ \theta θ) 得到生成图片的分布。
优化的目标是,对于给定的图片 x i x^i xi, 生成网络生成 x i x^i xi的概率越大越好。
最大化生成分布和真实分布的相似性 等价于 最小化二者的KL散度,推理步骤如下:
第一行:取log 并不印象最大化的计算
第二行:根据log的计算性质进行变换 l o g ( x 1 ) ∗ l o g ( x 2 ) = l o g ( x 1 + x 2 ) log(x_1)*log(x_2)=log(x_1+x_2) log(x1)∗log(x2)=log(x1+x2); 最终的求和式子近似于计算 期望值
第三行:用连续积分的形式计算期望,后面减去的部分是和 θ \theta θ 不相关的,不会影响最大化的结果。
第四行: l o g ( x 1 − x 2 ) = l o g ( x 1 ) / l o g ( x 2 ) log(x_1-x_2)=log(x_1)/ log(x_2) log(x1−x2)=log(x1)/log(x2) 最终变换成KL散度的形式。
详细数学推导
数学基础
高斯分布
定义:随机变量X服从一个数学期望 μ \mu μ、方差为 σ \sigma σ的高斯分布,又名正态分布。
当 μ = 0 , σ = 1 \mu=0, \sigma=1 μ=0,σ=1时的正态分布是标准正态分布。
高斯分布概率密度函数(正态随机变量概率密度函数):
f ( x ) = 1 2 π σ exp ( − ( x − μ ) 2 2 σ 2 ) f(x)=\frac{1}{\sqrt{2 \pi} \sigma} \exp \left(-\frac{(x-\mu)^2}{2 \sigma^2}\right) f(x)=2πσ1exp(−2σ2(x−μ)2)
两个高斯分布相加
已知两个独立的高斯分布:
N 1 ∼ ( u 1 , δ 1 2 ) , N 2 ∼ ( u 2 , δ 2 2 ) N_1 \sim\left(u_1, \delta_1^2\right), N_2 \sim\left(u_2, \delta_2^2\right) N1∼(u1,δ12),N2∼(u2,δ22)
这两个高斯分布的和,仍然是一个高斯分布
N 1 + N 2 ∼ ( u 1 + u 2 , δ 1 2 + δ 2 2 ) N_1+N_2 \sim\left(u_1+u_2, \delta_1^2+\delta_2^2\right) N1+N2∼(u1+u2,δ12+δ22)
同理,这两个高斯分布的差为:
N 1 − N 2 ∼ ( u 1 − u 2 , δ 1 2 + δ 2 2 ) N_1-N_2 \sim\left(u_1-u_2, \delta_1^2+\delta_2^2\right) N1−N2∼(u1−u2,δ12+δ22)
重参数化
N ( μ , σ 2 ) = μ + σ ∗ ϵ N\left(\mu, \sigma^2\right)=\mu+\sigma * \epsilon N(μ,σ2)=μ+σ∗ϵ
其中 ϵ \epsilon ϵ来自于 N ( 0 , 1 ) \mathcal{N}(0,1) N(0,1)
贝叶斯定理
条件概率:在已知一个事件 B B B 发生的情况下,此时另一个事件A发生的概率,符号表示为 P ( A ∣ B ) P(A \mid B) P(A∣B) ,它等于联合概率 P ( A , B ) P(A, B) P(A,B) 除以边缘分布 P ( B ) P(B) P(B), 即:
P ( A ∣ B ) = P ( A , B ) P ( B ) P(A \mid B)=\frac{P(A, B)}{P(B)} P(A∣B)=P(B)P(A,B)
或可以写成:
P ( A , B ) = P ( A ∣ B ) ⋅ P ( B ) P(A, B)=P(A \mid B) \cdot P(B) P(A,B)=P(A∣B)⋅P(B)
表示事件A,B联合概率等于在B发生的条件下A发生的条件概率乘以B事件发生概率。
由于P(A,B)也等于P(B|A)P(A) (P(A,B)与P(B,A)含义相同,数值相等),所以推导出贝叶斯公式:
P ( A ∣ B ) = P ( A , B ) P ( B ) = P ( B ∣ A ) ⋅ P ( A ) P ( B ) P(A \mid B)=\frac{P(A, B)}{P(B)}=\frac{P(B \mid A) \cdot P(A)}{P(B)} P(A∣B)=P(B)P(A,B)=P(B)P(B∣A)⋅P(A)
KL散度
向前扩散过程
给定从真实数据分布中采样的数据点 x 0 ∼ q ( x ) \mathbf{x}_0 \sim q(\mathbf{x}) x0∼q(x),让我们定义一个前向扩散过程,在其中我们在 T T T 步中向样本添加小量的高斯噪声,产生一系列带有噪声的样本 x 1 , … , x T \mathbf{x}_1, \ldots, \mathbf{x}_T x1,…,xT。步长由方差调度 { β t ∈ ( 0 , 1 ) } t = 1 T \left\{\beta_t \in(0,1)\right\}_{t=1}^T {βt∈(0,1)}t=1T控制。
q ( x t ∣ x t − 1 ) = N ( x t ; 1 − β t x t − 1 , β t I ) q ( x 1 : T ∣ x 0 ) = ∏ t = 1 T q ( x t ∣ x t − 1 ) q\left(\mathbf{x}_t \mid \mathbf{x}_{t-1}\right)=\mathcal{N}\left(\mathbf{x}_t ; \sqrt{1-\beta_t} \mathbf{x}_{t-1}, \beta_t \mathbf{I}\right) \quad q\left(\mathbf{x}_{1: T} \mid \mathbf{x}_0\right)=\prod_{t=1}^T q\left(\mathbf{x}_t \mid \mathbf{x}_{t-1}\right) q(xt∣xt−1)=N(xt;1−βtxt−1,βtI)q(x1:T∣x0)=t=1∏Tq(xt∣xt−1)
随着步长 t t t的增大,数据样本 x 0 \mathbf{x_0} x0逐渐失去其可区分的特征。最终,当 T T T趋向于正无穷时, x t \mathbf{x_t} xt等效于一个各向同性的高斯分布。
我们可以使用重参数化技巧在任意时间步 t t t中以封闭形式对 x t \mathbf{x_t} xt进行采样。
令 α t = 1 − β t \alpha_t=1-\beta_t αt=1−βt , α ˉ t = ∏ i = 1 t α i \bar{\alpha}_t=\prod_{i=1}^t \alpha_i αˉt=∏i=1tαi
x t = α t x t − 1 + 1 − α t ϵ t − 1 ; where ϵ t − 1 , ϵ t − 2 , ⋯ ∼ N ( 0 , I ) = α t α t − 1 x t − 2 + 1 − α t α t − 1 ϵ ˉ t − 2 ; where ϵ ‾ t − 2 merges two Gaussians ( ∗ ) . = … = α ˉ t x 0 + 1 − α ˉ t ϵ q ( x t ∣ x 0 ) = N ( x t ; α ˉ t x 0 , ( 1 − α ˉ t ) I ) \begin{aligned} & \mathbf{x}_t=\sqrt{\alpha_t} \mathbf{x}_{t-1}+\sqrt{1-\alpha_t} \boldsymbol{\epsilon}_{t-1} \quad \quad ; \text { where } \boldsymbol{\epsilon}_{t-1}, \boldsymbol{\epsilon}_{t-2}, \cdots \sim \mathcal{N}(\mathbf{0}, \mathbf{I}) \\ & =\sqrt{\alpha_t \alpha_{t-1}} \mathbf{x}_{t-2}+\sqrt{1-\alpha_t \alpha_{t-1}} \bar{\epsilon}_{t-2} \quad ; \text { where } \overline{\boldsymbol{\epsilon}}_{t-2} \text { merges two Gaussians }\left(^*\right) \text {. } \\ & =\ldots \\ & =\sqrt{\bar{\alpha}_t} \mathbf{x}_0+\sqrt{1-\bar{\alpha}_t} \boldsymbol{\epsilon} \\ & q\left(\mathbf{x}_t \mid \mathbf{x}_0\right)=\mathcal{N}\left(\mathbf{x}_t ; \sqrt{\bar{\alpha}_t} \mathbf{x}_0,\left(1-\bar{\alpha}_t\right) \mathbf{I}\right) \\ & \end{aligned} xt=αtxt−1+1−αtϵt−1; where ϵt−1,ϵt−2,⋯∼N(0,I)=αtαt−1xt−2+1−αtαt−1ϵˉt−2; where ϵt−2 merges two Gaussians (∗). =…=αˉtx0+1−αˉtϵq(xt∣x0)=N(xt;αˉtx0,(1−αˉt)I)
将两个具有不同方差的高斯分布
N ( 0 , σ 1 2 I ) \mathcal{N}\left(\mathbf{0}, \sigma_1^2 \mathbf{I}\right) N(0,σ12I) 和 N ( 0 , σ 2 2 I ) \mathcal{N}\left(\mathbf{0}, \sigma_2^2 \mathbf{I}\right) N(0,σ22I)合并,得到的新的分布是: N ( 0 , ( σ 1 2 + σ 2 2 ) I ) \mathcal{N}\left(\mathbf{0},\left(\sigma_1^2+\sigma_2^2\right) \mathbf{I}\right) N(0,(σ12+σ22)I).
将 x t − 1 = α t − 1 x t − 2 + 1 − α t − 1 ϵ t − 2 \mathbf{x}_{t-1}=\sqrt{\alpha_{t-1}} \mathbf{x}_{t-2}+\sqrt{1-\alpha_{t-1}} \boldsymbol{\epsilon}_{t-2} xt−1=αt−1xt−2+1−αt−1ϵt−2 代入当上式中,得到:
x t = a t ( a t − 1 x t − 2 + 1 − α t − 1 ϵ 2 ) + 1 − α t z 1 = a t a t − 1 x t − 2 + ( a t ( 1 − α t − 1 ) ϵ 2 + 1 − α t z 1 ) x_t=\sqrt{a_t}\left(\sqrt{a_{t-1}} x_{t-2}+\sqrt{1-\alpha_{t-1}} \boldsymbol{\epsilon}_2\right)+\sqrt{1-\alpha_t} z_1 \\ =\sqrt{a_t a_{t-1}} x_{t-2}+\left(\sqrt{a_t\left(1-\alpha_{t-1}\right)}\boldsymbol{\epsilon}_2+\sqrt{1-\alpha_t} z_1\right) xt=at(at−1xt−2+1−αt−1ϵ2)+1−αtz1=atat−1xt−2+(at(1−αt−1)ϵ2+1−αtz1)
由于每次加入的噪音 ϵ 1 \boldsymbol{\epsilon}_1 ϵ1和 ϵ 2 \boldsymbol{\epsilon}_2 ϵ2都服从标准高斯分布 N ∼ ( 0 , I ) \mathcal{N} \sim (0, I) N∼(0,I)。
则 a t ( 1 − α t − 1 ) z 2 ∼ N ( 0 , a t ( 1 − a t − 1 ) ) \sqrt{a_t\left(1-\alpha_{t-1}\right)} z_2 \sim N (0, a_t(1-a_{t-1})) at(1−αt−1)z2∼N(0,at(1−at−1)) , 1 − α t z 1 ∼ N ( 1 − a t ) \sqrt{1-\alpha_t} z_1 \sim N(1-a_t) 1−αtz1∼N(1−at)
这两个分布相加
a t ( 1 − α t − 1 ) z 2 + 1 − α t z 1 ∼ N ( 0 , ( 1 − α t ) + α t ( 1 − α t − 1 ) ) = N ( 0 , 1 − α t α t − 1 ) \sqrt{a_t\left(1-\alpha_{t-1}\right)} z_2 + \sqrt{1-\alpha_t} z_1 \sim N(0, \left(1-\alpha_t\right)+\alpha_t\left(1-\alpha_{t-1}\right) )=N(0, 1-\alpha_t \alpha_{t-1}) at(1−αt−1)z2+1−αtz1∼N(0,(1−αt)+αt(1−αt−1))=N(0,1−αtαt−1)
通常,当sample变的noise后,我们可以采用更大的更新率。因此 β 1 < β 2 < ⋯ < β T \beta_1<\beta_2<\cdots<\beta_T β1<β2<⋯<βT , α ˉ 1 > ⋯ > α ˉ T \bar{\alpha}_1>\cdots>\bar{\alpha}_T αˉ1>⋯>αˉT.
与随机梯度Langevin动力学的联系
Langevin 动力学是物理学中的一个概念,用于统计建模分子系统。结合随机梯度下降,随机梯度 Langevin 动力学( stochastic gradient Langevin dynamics)可以使用更新的马尔可夫链中的梯度 ∇ x log p ( x ) \nabla_{\mathbf{x}} \log p(\mathbf{x}) ∇xlogp(x)来从概率密度 p ( x ) p(\mathbf{x}) p(x)中产生样本:
x t = x t − 1 + δ 2 ∇ x log p ( x t − 1 ) + δ ϵ t , where ϵ t ∼ N ( 0 , I ) \mathbf{x}_t=\mathbf{x}_{t-1}+\frac{\delta}{2} \nabla_{\mathbf{x}} \log p\left(\mathbf{x}_{t-1}\right)+\sqrt{\delta} \boldsymbol{\epsilon}_t, \quad \text { where } \boldsymbol{\epsilon}_t \sim \mathcal{N}(\mathbf{0}, \mathbf{I}) xt=xt−1+2δ∇xlogp(xt−1)+δϵt, where ϵt∼N(0,I)
其中 δ \delta δ 是 step size. 当 T → ∞ , ϵ → 0 , x T T \rightarrow \infty, \epsilon \rightarrow 0, \mathbf{x}_T T→∞,ϵ→0,xT 等同于true probability density p ( x ) p(\mathbf{x}) p(x).
与标准随机梯度下降相比,随机梯度 Langevin 动力学在参数更新中注入高斯噪声,以避免陷入局部最小值。
反向去噪过程
如果我们能够反转上述过程并从 q ( x t − 1 ∣ x t ) q\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right) q(xt−1∣xt) 中采样,我们将能够从高斯噪声输入 x T ∼ N ( 0 , I ) \mathbf{x}_T \sim \mathcal{N}(\mathbf{0}, \mathbf{I}) xT∼N(0,I) 中重新创建真实样本。请注意,如果 β t \beta_t βt 足够小, q ( x t − 1 ∣ x t ) q\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right) q(xt−1∣xt) 也将是高斯分布。不幸的是,我们无法轻松地估计 q ( x t − 1 ∣ x t ) q\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right) q(xt−1∣xt),因为它需要使用整个数据集,因此我们需要学习一个模型 p θ p_\theta pθ 来近似这些条件概率,以便运行反向扩散过程。
p θ ( x 0 : T ) = p ( x T ) ∏ t = 1 T p θ ( x t − 1 ∣ x t ) p θ ( x t − 1 ∣ x t ) = N ( x t − 1 ; μ θ ( x t , t ) , Σ θ ( x t , t ) ) p_\theta\left(\mathbf{x}_{0: T}\right)=p\left(\mathbf{x}_T\right) \prod_{t=1}^T p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right) \quad p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right)=\mathcal{N}\left(\mathbf{x}_{t-1} ; \boldsymbol{\mu}_\theta\left(\mathbf{x}_t, t\right), \mathbf{\Sigma}_\theta\left(\mathbf{x}_t, t\right)\right) pθ(x0:T)=p(xT)t=1∏Tpθ(xt−1∣xt)pθ(xt−1∣xt)=N(xt−1;μθ(xt,t),Σθ(xt,t))
当条件是 x 0 \mathcal{x_0} x0时,反向条件概率是可处理的。
使用Bayes法则,可以得到
其中 C ( x t , x 0 ) C\left(\mathbf{x}_t, \mathbf{x}_0\right) C(xt,x0) 是某个不涉及 x t − 1 \mathbf{x}_{t-1} xt−1 的常数项,不影响。
对于上式的第一行,利用贝叶斯定理展开后的三项都是已知的:
q ( x t − 1 ∣ x 0 ) a t ‾ − 1 x 0 + 1 − a t ‾ − 1 ∼ N ( a t ‾ − 1 , x 0 , 1 − a t − 1 ‾ ) q ( x t ∣ x 0 ) α ˉ t x 0 + 1 − α ˉ t z ∼ N ( α ˉ t x 0 , 1 − α ˉ t ) q ( x t ∣ x t − 1 , x 0 ) = a t x t − 1 + 1 − α t z ∼ N ( a t x t − 1 , 1 − α t ) \begin{aligned} & q\left(\mathbf{x}_{t-1} \mid \mathbf{x}_0\right) \quad \sqrt{\overline{a_t}-1} x_0+\sqrt{1-\overline{a_t}}-1 \quad \sim \mathcal{N}\left(\sqrt{\overline{a_t}}-1, x_0, 1-\overline{a_{t-1}}\right) \\ & q\left(\mathbf{x}_t \mid \mathbf{x}_0\right) \quad \sqrt{\bar{\alpha}_t} x_0+\sqrt{1-\bar{\alpha}_t} z \quad \sim \mathcal{N}\left(\sqrt{\bar{\alpha}_t} x_0, 1-\bar{\alpha}_t\right) \\ & q\left(\mathbf{x}_t \mid \mathbf{x}_{t-1}, \mathbf{x}_0\right)=\sqrt{a_t} x_{t-1}+\sqrt{1-\alpha_t} z \quad \sim \mathcal{N}\left(\sqrt{a_t} x_{t-1}, 1-\alpha_t\right) \end{aligned} q(xt−1∣x0)at−1x0+1−at−1∼N(at−1,x0,1−at−1)q(xt∣x0)αˉtx0+1−αˉtz∼N(αˉtx0,1−αˉt)q(xt∣xt−1,x0)=atxt−1+1−αtz∼N(atxt−1,1−αt)
将标准正态分布展开之后,因为是指数运算,乘法相当于加法,除法相当于减法。因此可以得到第二行。
第三行和第四行进行展开成如下的格式:
exp ( − ( x − μ ) 2 2 σ 2 ) = exp ( − 1 2 ( 1 σ 2 x 2 − 2 μ σ 2 x + μ 2 σ 2 ) ) \exp \left(-\frac{(x-\mu)^2}{2 \sigma^2}\right)=\exp \left(-\frac{1}{2}\left(\frac{1}{\sigma^2} x^2-\frac{2 \mu}{\sigma^2} x+\frac{\mu^2}{\sigma^2}\right)\right) exp(−2σ2(x−μ)2)=exp(−21(σ21x2−σ22μx+σ2μ2))
这样可以进一步的进行配方,得到均值和方差。
按照标准高斯密度函数,均值和方差可以参数化如下(回想一下 α t = 1 − β t \alpha_t=1-\beta_t αt=1−βt 和 α ˉ t = ∏ i = 1 T α i ) \left.\bar{\alpha}_t=\prod_{i=1}^T \alpha_i\right) αˉt=∏i=1Tαi)
上式均值中 x 0 x_0 x0是未知的,但是我们可以通过从 x 0 x_0 x0生成 x t x_t xt的公式逆过来,得到 x 0 = 1 α ˉ t ( x t − 1 − α ˉ t ϵ t ) \mathbf{x}_0=\frac{1}{\sqrt{\bar{\alpha}_t}}\left(\mathbf{x}_t-\sqrt{1-\bar{\alpha}_t} \epsilon_t\right) x0=αˉt1(xt−1−αˉtϵt) 代入上式,得到:
然而 ϵ t \epsilon_t ϵt仍然是未知的,这个就是用Unet预测的每个时刻的噪音。
Stable Diffusion
Stable Diffusion(SD)模型,可以用于文生图,图生图,图像inpainting,ControlNet控制生成,图像超分等丰富的任务。
- 文生图任务是指将一段文本输入到SD模型中,经过一定的迭代次数,SD模型输出一张符合输入文本描述的图片。
- 图生图任务在输入本文的基础上,再输入一张图片,SD模型将根据文本的提示,将输入图片进行重绘以更加符合文本的描述。
组成结构
Stable Diffusion 是一个系统,由几个组件和模型构成,而非单独一个模型。
Text Encoder
功能:对输入的文本进行编码。
实现:CLIP 模型中的文本编码器
输入:文本
输出:77个表征向量,每个有768维度
Image Information Creator
功能:逐渐处理/扩散信息到潜在(信息)空间。
实现:Unet网络+Scheduler
输入:文本向量 和 起始多维数组(结构化的数字列表,也叫Tensor)由噪声组成。
输出:处理后的信息数组
输入:
1) 如果是图生图任务,我们在输入文本信息的同时,还需要将原图片通过图像编码器(VAE Encoder)生成Latent Feature(隐空间特征)作为输入。
2) 如果是文生图任务,我们只需要输入文本信息,再用random函数生成一个高斯噪声矩阵作为Latent Feature的“替代”输入
组成:
1)U-Net网络负责预测噪声,不断优化生成过程,在预测噪声的同时不断注入文本语义信息。
2)schedule算法对每次U-Net预测的噪声进行优化处理(动态调整预测的噪声,控制U-Net预测噪声的强度),从而统筹生成过程的进度。
Image Decoder
图像解码器通过前置信息生成器得到的信息来生成图像。它只在最后的运行一次来生成最终的像素图像。
输入:处理过的信息数组(维度:(4,64,64))
输出:结果图像(维度:(3,512,512)分别是红/绿/蓝,宽,高)
运行流程
Step 1: 将输入的文本提示通过Text Encoder进行编码, 作为Diffusion 的输入。
Step 2:将随机采样的噪音,也作为Diffusion的输出。
Step 3: 得到处理后的Image information 作为图像解码器的输入。
Diffusion 的过程是step-by-step 的,逐步生成清晰的图片。
下图通过图像解码器可视化每个步骤
扩散动作发生了多次,每一步都对输入潜在数组上操作以产生更相似于输入文本的新潜在数组,视觉信息来自于模型从所有图像训练语料。
下图可视化一系列的这些潜在数组:
在SD中,U-Net的迭代优化步数(Timesteps)大概是50或者100次,在这个过程中Latent Feature的质量不断的变好(纯噪声减少,图像语义信息增加,文本语义信息增加)
回顾Diffusion Model的内部工作原理
假设我们有张图片,我们生成了一些噪声,然后把噪声添加到图像上。
我们使用相同的方式来生成大量的训练样本。
使用这份数据集,我们可以训练噪声预测器
训练好的噪声预测器可以产生一个噪声图像,接来下的一系列降噪步骤,可以预测噪声。
采样噪声被预测了出来,所以如果我们从图像中减去它就能得到尽可能接近于模型训练样本的图像
逐步得到最终的生成图像
潜在空间
之前的Diffusion Model 不管是前向扩散过程还是反向扩散过程,都需要在像素级的图像上进行,当图像分辨率和Timesteps很大时,不管是训练还是前向推理,都非常的耗时。
而Stable Diffusion 将这些过程压缩在低维的Latent隐空间,这样一来大大降低了显存占用和计算复杂度
为了加速图像生成的过程,Stable Diffusion 是在图像的压缩空间上扩散操作。
压缩(和稍后的解压缩/绘制)是经由自编码器完成的。自编码器通过编码器压缩图像到潜在空间,然后只用压缩信息来解码重建。
在压缩空间上进行前向扩散过程。噪声数据是用在这些潜在空间上的,而非像素图片上的。所以,噪声预测器实际上是被训练在压缩表示上(潜在空间)来预测噪声的。
一旦训练完后,我们就可以通过反向处理(使用自编码器的解码器)来生成图像。
总结一下SD模型的前向推理过程:
网络结构
Stable Diffusion模型主要由VAE
(变分自编码器,Variational Auto-Encoder),U-Net
以及CLIP Text
Encoder三个核心组件构成。
VAE 模型
VAE(变分自编码器,Variational Auto-Encoder)是基于Encoder-Decoder架构的生成模型。VAE的Encoder(编码器)结构能将输入图像压缩为低维Latent特征,并作为U-Net的输入。VAE的Decoder(解码器)结构能将低维Latent特征重建还原成像素级图像。
VAE的核心作用
1) 图像压缩和图像重建
如下图所示:
当我们输入一个尺寸为 H × W × C H\times W\times C H×W×C的数据,VAE的Encoder模块会将其编码为一个大小为 h × w × c h\times w\times c h×w×c 的低维Latent特征,其中 f = H / h = W / w f=H/h=W/w f=H/h=W/w为VAE的下采样率(Downsampling Factor)。反之,VAE的Decoder模块有一个相同的上采样率(Upsampling Factor)将低维Latent特征重建成像素级别的图像。
为什么VAE可以将图像压缩到一个非常小的Latent space(潜空间)后能再次对图像进行像素级重建呢?
因为虽然VAE对图像的压缩与重建过程是一个有损压缩与重建过程,但图像全图级特征关联并不是随机的,它们的分布具有很强的规律性:比如人脸的眼睛、鼻子、脸颊和嘴巴之间遵循特定的空间关系,又比如一只猫有四条腿,并且这是一个特定的生物结构特征。下面Rocky也使用VAE将图像重建成不同尺寸的生成图像,实验结论发现如果我们重建生成的图像尺寸在之上时,其实特征损失带来的影响非常小。
2) 切换不同微调训练版本的VAE模型,能够发现生成图片的细节与整体颜色也会随之改变
VAE的网络结构
VAE中Encoder和Decoder的结构如下:
- SD VAE Encoder部分包含了三个DownBlock模块、一个ResNetBlock模块以及一个MidBlock模块,将输入图像压缩到Latent空间,转换成为Gaussian Distribution。
- 而VAE Decoder部分正好相反,其输入Latent空间特征,并重建成为像素级图像作为输出。其包含了三个UpBlock模块、一个ResNetBlock模块以及一个MidBlock模块。
三个基础组件:
GSC
组件:GroupNorm+Swish+ConvDownsample
组件:Padding+ConvUpsample
组件:Interpolate+Conv
两个核心组件:ResNetBlock
模块SelfAttention
模型
文本编码器
Stable Diffusion 中采用的文本编码器是CLIP模型中的文本编码器
CLIP模型的训练过程如下:
CLIP在4亿张图像及其对应字幕数据集上做训练。
- 输入图像及其描述,然后使用对应的编码器各自做图像和文本编码。
- 用余弦相似来对比上述两个编码向量,当我们开始训练过程之后,相似值会变小,即便文本正确地描述了图像。
- 更新两个编码模型,以使得下次编码向量更相似。
将编码后的文本信息,也作为噪音生成器的输入。
由于我们将要在潜在空间中操作,所以输入的图像和已经预测的噪声都是在潜在空间的。
噪音预测器
下图展示了不用文本的扩散Unet, 输入是在潜在空间中的噪音图片和时间步长。
通过在ResNet模块之间增加一个Attention层,添加对文本输入的支持。
ResNet模块并不能直接看到文本,但是Attention层将文本表达合并到了潜在空间。现在接下来的ResNet可以使用合并过来的文本信息到它的处理过程了。
Unet 模型
Unet模型的作用
预测噪声残差
,并结合Sampling method(调度算法:DDPM、DDIM、DPM++等)对输入的特征矩阵进行重构,逐步将其从随机高斯噪声转化成图片的Latent Feature。
在前向推理过程中,SD模型通过反复调用 U-Net,将预测出的噪声残差从原噪声矩阵中去除,得到逐步去噪后的图像Latent Feature,再通过VAE的Decoder结构将Latent Feature重建成像素级图像。
Unet 模型的结构
Stable Diffusion中的U-Net,在传统深度学习时代的Encoder-Decoder结构的基础上,增加了ResNetBlock
(包含Time Embedding)模块,Spatial Transformer
(SelfAttention + CrossAttention + FeedForward)模块以及CrossAttnDownBlock
,CrossAttnUpBlock
和CrossAttnMidBlock
模块。
-
ResNetBlock模块
:借鉴ResNet模型的“残差结构”,让网络能够构建的更深的同时,将Time Embedding信息嵌入模型。 -
GSC模块
:Stable Diffusion U-Net中的最小组件之一,由GroupNorm+SiLU+Conv
三者组成。 -
DownSample模块
:Stable Diffusion U-Net中的下采样组件,使用了Conv(kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
进行采下采样。 -
UpSample模块
:Stable Diffusion U-Net中的上采样组件,由插值算法(nearest)+Conv组成。 -
UpBlock_X模块
:由X个ResNetBlock模块和一个UpSample模块
组成。
-
CrossAttnDownBlock_X模块
:是Stable Diffusion U-Net中Encoder部分的主要模块,由X个(ResNetBlock模块+Spatial Transformer模块)+DownSample模块
组成。 -
CrossAttnMidBlock模块
:是Stable Diffusion U-Net中Encoder和ecoder连接的部分,由ResNetBlock+Spatial Transformer+ResNetBlock组成
。
-
FeedForward模块
:Attention机制中的经典模块,由GeGlU+Dropout+Linear
组成。 -
CrossAttnUpBlock_X模块
:是Stable Diffusion U-Net中Decoder部分的主要模块,由X个(ResNetBlock模块+Spatial Transformer模块)+UpSample模块
组成。 -
Spatial Transformer模块
:由GroupNorm+Conv+BasicTransformer Block+Conv
构成
-
BasicTransformer Block模块
:由LayerNorm+SelfAttention+CrossAttention+FeedForward
组成,是多重Attention机制的级联,并且也借鉴ResNet模型的“残差结构”。通过加深网络和多Attention机制,大幅增强模型的学习能力与图文的匹配能力。 -
SelfAttention模块
:SelfAttention模块的整体结构与CrossAttention模块相同,这是输入全部都是图像信息,不再输入文本信息。
-
CrossAttention模块
:将文本的语义信息与图像的语义信息进行Attention机制,增强输入文本Prompt对生成图片的控制。
训练过程和损失函数
在Stable Diffusion中,需要对VAE模型进行微调训练,主要采用了L1回归损失
和感知损失
(perceptual loss,Learned Perceptual Image Patch Similarity,LPIPS)作为损失函数,同时使用了基于patch的对抗训练策略
。
为了防止在Latent空间的任意缩放导致的标准差过大,在训练VAE模型的过程中引入了正则化损失
L1回归损失
L1回归损失用在回归问题中衡量预测值与真实值之间的差异。
L 1 ( y , y ^ ) = ∑ i = 1 n ∣ y i − y ^ i ∣ L 1(y, \hat{y})=\sum_{i=1}^n\left|y_i-\hat{y}_i\right| L1(y,y^)=i=1∑n∣yi−y^i∣
其中, y i y_i yi 是输入数据的真实值, y ^ i \hat{y}_i y^i 是模型生成数据的预测值, n n n 是数据总数。
感知损失
感知损失的核心思想是比较原始图像和生成图像在传统深度学习模型(VGG、ResNet、ViT等)不同层中特征图之间的相似度,而不直接进行像素级别的对比。传统深度学习模型能够提取图像的高维语义信息的特征,如果两个图像在高维语义信息的特征上接近,那么它们在像素级别的语意上也应该是相似的。
感知损失的公式如下所示:
L perceptual = ∑ l λ l ⋅ ∥ ϕ l ( I pred ) − ϕ l ( I target ) ∥ 2 2 L_{\text {perceptual }}=\sum_l \lambda_l \cdot\left\|\phi_l\left(I_{\text {pred }}\right)-\phi_l\left(I_{\text {target }}\right)\right\|_2^2 Lperceptual =l∑λl⋅∥ϕl(Ipred )−ϕl(Itarget )∥22
其中: ϕ l \phi_l ϕl 表示在预训练模型 (比如VGG/ResNet网络) 的第 l l l 层的激活特征。 I p r e d I_{p r e d} Ipred 是模型生成的图像。 I target I_{\text {target }} Itarget 是真实图像。 λ l \lambda_l λl 是第 l l l 层的权重,可以根据实际情况设置合适值。
正则化损失
KL(Kullback-Leibler)
正则化
让Latnet特征不要偏离正态分布太远,同时设置了较小的权重(~10e-6)来保证VAE的重建效果。VQ(Vector Quantization)
正则化
过在decoder模块中引入一个VQ-layer,将VAE转换成VQ-GAN,同样为了保证VAE的重建效果,设置较高的codebook采样维度(8192)。
虽然VAE模型使用了KL正则化,但是由于KL正则化的权重系数非常小,实际生成的Latent特征的标准差依旧存在比较大的情况,所以Stable Diffusion论文中提出了一种rescaling方法强化正则效果。
首先我们计算第一个batch数据中Latent特征的标准差 σ \sigma σ ,然后采用 1 / σ 1 / \sigma 1/σ 的系数来rescale后续所有的Latent特征使其标准差接近于1。同时在Decoder模块进行重建时,只需要将生成的Latent 特征除以 1 / σ 1 / \sigma 1/σ ,再进行像素级重建即可。
在SD中,U-Net模型使用的是经过rescaling后的Latent 特征,并且将rescaling系数设置为 0.18215 。
基于patch的对抗训练策略
使用PatchGAN的判别器来对VAE模型进行对抗训练,通过优化判别器损失,来提升生成图像的局部真实性(纹理和细节)与清晰度。
PatchGAN是GAN系列模型的一个变体,其判别器架构不再评估整个生成图像是否真实,而是评估生成图像中的patch部分是否真实。具体来说,PatchGAN的判别器接收一张图像,并输出一个矩阵,矩阵中的每个元素代表图像中对应区域的真实性。
总损失函数
Diffusion中VAE训练的完整损失函数:
L Autoencoder = min E , D max ψ ( L r e c ( x , D ( E ( x ) ) ) − L a d v ( D ( E ( x ) ) ) + log D ψ ( x ) + L r e g ( x ; E , D ) ) \begin{gathered} \mathcal{L}_{\text {Autoencoder }}=\min _{\mathcal{E}, \mathcal{D}} \max _\psi \\ \left(\mathcal{L}_{r e c}(x, \mathcal{D}(\mathcal{E}(x)))-\mathcal{L}_{a d v}(\mathcal{D}(\mathcal{E}(x)))+\log \mathcal{D}_\psi(x)+\mathcal{L}_{r e g}(x ; \mathcal{E}, \mathcal{D})\right) \end{gathered} LAutoencoder =E,Dminψmax(Lrec(x,D(E(x)))−Ladv(D(E(x)))+logDψ(x)+Lreg(x;E,D))
其中 E ( x ) \mathcal{E}(x) E(x) 表示VAE重建的图像, L r e c \mathcal{L}_{r e c} Lrec 表示L1回归损失和感知损失, L a d v + log D ψ \mathcal{L}_{a d v}+\log \mathcal{D}_\psi Ladv+logDψ 表示 PachGAN的判别器损失, L r e g \mathcal{L}_{r e g} Lreg 表示KL正则损失。
参考
论文
【1】 DDPM的灵感来源 Deep Unsupervised Learning using Nonequilibrium Thermodynamics
【2】DDPM 开山之作 : Denoising Diffusion Probabilistic Models (DDPM)
【3】DDPM的改进,提出余弦调度策略 Improved Denoising Diffusion Probabilistic Models
【4】DDPM采用的最基础的Unet架构U-Net: Convolutional Networks for Biomedical Image Segmentation
博文
【b.1】通过可视化的动画,逐步讲解 Step by Step Visual Introduction to Diffusion Models
【b.2】主页里有对应的ppt和yotube链接 cvpr2022-tutorial-diffusion-models
【b.3】偏向于数学的角度介绍 How diffusion models work: the math from scratch
【b.4】Arxiv24最新的一篇关于DDPM非常详细的讲解 Tutorial on Diffusion Models for Imaging and Vision
【b.5】介绍的非常全面,包括具体的数学推导What are Diffusion Models?
【b.6】Stable Diffusion 图解 The Illustrated Stable Diffusion
【b.7】强烈推荐知乎上的一个讲解 深入浅出完整解析Stable Diffusion(SD)核心基础知识
视频
【1】李宏毅老师的系列讲解
【生成式AI】淺談圖像生成模型 Diffusion Model 原理
【生成式AI】Stable Diffusion、DALL-E、Imagen 背後共同的套路
【生成式AI】Diffusion Model 原理剖析 (1/4) (optional)
【生成式AI】Diffusion Model 原理剖析 (2/4) (optional)
【生成式AI】Diffusion Model 原理剖析 (3/4) (optional)
【生成式AI】Diffusion Model 原理剖析 (4/4) (optional)
【2】Yotube上的视频,不仅介绍了DDPM基础还有应用
Tutorial on Denoising Diffusion-based Generative Modeling: Foundations and Applications