扩散模型:生成扩散模型
目前的内容来源于《Transformer视觉系列遨游》系列的整理过程。最近,Transformer在AI绘画领域非常火爆。 AI绘画效果从2022年DeepDream[1]的噩梦中醒来,2022年开始吸引来自OpenAI的DALL·E 2[2]的插画效果和联想效果,取得了惊人的成果。虽然看不懂,但是这个话题对ZOMI来说非常有吸引力,所以我会看一下这个领域的内容,看看有哪些有趣的技术点。
但你需要明白:Transformer带来AI+艺术,从语言出发,遭遇多模态,碰撞出艺术火花这个话题需要很多额外的知识点,可能是密切相关的CV、NLP等领域创造奇迹的方式是不同的。除了遇到Transformer结构之外,AI+艺术还会涉及到VAE、ELBO、Diffusion Model等一系列数学相关知识。
变形金刚+艺术系列中,今天挖了一个新坑,叫Diffusion Models。像VAE一样,原理非常复杂,实现也非常粗糙。据说生成扩散模型以其数学复杂性而闻名,似乎比 VAE 和 GAN 更难理解。这是真的?扩散模型可以少用一点数学吗?难道真的无法用更简单的方式理解扩散模型吗?
在本文中,我们将研究扩散模型的理论基础,然后演示如何使用扩散模型在 PyTorch 中生成图像。让我们潜入吧!
扩散模型自发表以来并没有受到太多关注,因为它们不像 GAN 那样简单、粗暴和易于理解。然而,近年来,生成模型领域出现了。两种最先进的文本生成图像,OpenAI的DALL·E 2和Google的Imagen,都是基于扩散模型的。
当前生成扩散模型的趋势始于2020年提出的DDPM(去噪扩散概率模型)。仅2020年发表的开创性论文DDPM就向世界展示了扩散模型在图像合成方面的能力。在性能方面,它击败了GAN[6],因此后续很多图像生成领域开始转向DDPM研究领域。
看了网上很多文章,在介绍DDPM时,介绍了概率转移分布,然后是变分推理,然后是最大似然解法,介绍了证据下界(Evidence Lower Bound)。这几周一堆数学符号把我吓跑了(当然,从这个介绍我们又可以看到,DDPM和VAE的理论关系其实很密切),再加上人们对传统扩散模型固有的印象,所以它形成了“需要非常深厚的数学知识”的错觉。
我们先来看看最近流行的生成模型:GAN、VAE、Flow-based Models、Diffusion Models。
GAN 由生成器(generator)和鉴别器(discriminator)组成。生成器负责生成真实的数据来“欺骗”鉴别器,而鉴别器则负责确定样本是真实的还是“制造的”。 GAN的训练实际上是两个模型互相学习。能不能称之为“对抗”,和谐一些?
VAE还希望训练一个生成模型x=g(z),它可以将采样的概率分布映射到训练集的概率分布。生成潜变量z,z既包含数据信息又包含噪声。除了恢复输入样本数据外,它还可以用于生成新数据。
扩散模型的灵感来自非平衡热力学。该理论首先定义了马尔可夫链的扩散步骤,以缓慢地将随机噪声添加到数据中,然后学习反向扩散过程,以从噪声中构建所需的数据样本。与 VAE 或流模型不同,扩散模型是通过固定过程学习的,并且潜在空间 z 具有相对较高的维度。
总体来说,扩散模型领域正处于蓬勃发展的状态。这个领域有点像GAN刚提出的时候。目前的训练技术可以让Diffusion Models在GAN领域直接跳过模型调整阶段,可以直接使用。做下游任务。
扩散模型称为生成模型,这意味着扩散模型用于生成与训练数据类似的数据。从根本上说,扩散模型的工作原理是不断添加高斯噪声来破坏训练数据,然后学习通过逆转噪声过程来恢复数据。
训练后,您可以使用扩散模型将随机采样的噪声传递到模型中,并通过学习去噪过程来生成数据。也就是下图对应的基本原理,不过这里的图还是有点粗。
更具体地说,扩散模型是使用马尔可夫链(MC)映射到潜在空间的潜在变量模型。通过马尔可夫链,通过马尔可夫链将噪声逐渐添加到数据xi">xi,得到后验概率 q( x1:T∣x0)">q(x1:T∣x0) ,其中 x 1,…,xT"> x1,…,xT表示输入数据也是潜在空间。说扩散模型的潜在空间与输入数据具有相同的维度。
马尔可夫链(MC)是概率论和数理统计中存在于离散索引集和状态空间中的具有马尔可夫性质的随机链。随机过程。
扩散模型分为正向扩散过程和反向扩散过程。下图是扩散过程,从x0">x0到最终的xT ">xT 这是只是Marco链代表了状态空间中从一种状态转变到另一种状态的随机过程。下标是Diffusion Models对应的图像扩散过程。
最后,从x0">x0输入的真实图像通过扩散模型渐近转换为纯高斯噪声图像xT ">xT。
模型训练主要关注逆扩散过程。训练扩散模型的目标是学习前向过程的逆过程:即训练概率分布 pθ(xt1) −1∣x t)">pθ(xt−1∣xt) .通过沿着马尔可夫链向后遍历,可以重新生成新的数据 x0">x0。读这个有点有趣。 Diffusion Models 与 GAN 或 VAE 最大的区别在于,它不是通过模型生成的,而是基于马尔可夫链,并且数据是通过学习噪声生成的。
除了生成有趣的高质量图像之外,扩散模型还有许多其他好处。其中最重要的是,训练过程中不需要对抗,整个世界都感觉很和平。因为对于GAN网络模型来说,对抗性训练其实是非常难调试的,因为对抗性训练过程中互相竞争的两个模型对我们来说就是一个黑匣子。此外,在训练效率方面,扩散模型还具有可扩展性和可并行性。加快训练过程,添加更多数学规则和约束,并将其扩展到语音、文本和三维领域,将会非常有趣。很多新文章。
上面已经明确指出,扩散模型由正向过程(或扩散过程)和反向过程(或逆扩散过程)组成,其中输入数据逐渐带有噪声,然后将噪声转换回源目标分布的样本。
如果不想深入理解数学原理,可以直接跳到代码实现部分。如果你还想了解一些基本的数学原理,可以继续阅读。其实它并不比GAN困难多少,只是一个马尔可夫链+条件概率分布。 核心在于如何利用神经网络模型来求解马尔可夫过程的概率分布。
前向过程 由于每个时间t只与时间t-1相关,因此可以将其视为马尔可夫过程。在马尔可夫链的前向采样过程中,即扩散过程中,可以将数据转化为高斯分布。即扩散过程通过T次累加在输入数据中添加高斯噪声xi">xi。结合马尔可夫假设,因此扩散过程表可达到:
(1)q(x1:T∣ x0):=∏ t=1Tq(xt∣xt−1):= ∏t=1TN(x t;1−βtxt−1,βtI )">(1)q(x1:T∣x0) : =∏t=1Tq(xt∣xt−1):=∏t=1TN(xt;1−βtxt−1,βtI)
哪里β1,…,βT ">β1,…,βT 是方差的上数在扩散过程中,随着t的增加,xt">xt越来越接近纯噪声。当T足够大时,xT">xT可以收敛到标准高斯噪声N (0,I)">N(0,I)。
然而,扩散模型的神奇“魔力”来自于反向扩散过程。如果说扩散过程是一个加噪声的过程,那么逆扩散过程就是一个去噪推理过程。如果我们能够逐渐得到逆分布 pθ(xt−1 ∣xt)">pθ(xt−1∣xt) ,可以由标准高斯分布N(0, 我) "> N(0,I) 恢复样本数据的分布x0">x0.
也就是说,在训练过程中,模型学习逆扩散过程的概率分布以生成新数据。如下图,由纯高斯噪声p(xT):= N(xT ;0,I)">p(xT):=N(xT;0,I ) 开始时,模型将学习联合概率分布 pθ(xT:0)">pθ(xT:0):
(2)pθ(xT: ):=p( xT)∏t=1Tp θ(xt −1∣xt):=p( xT)∏ t=1TN(xt−1;μθ(x t ,t),Σ θ (xt,t))">(2)pθ(xT:0):=p(xT)∏t=1Tpθ(xt−1∣xt):=p(xT)∏t=1TN (xt−1 ;μθ(xt,t),Σθ(xt,t))
根据马尔可夫规则,反向扩散过程当前时间步t仅取决于前一个时间步t-1,因此有:
(3)pθ(xt− ∣xt) : =N(xt−1;μ θ(xt ,t),Σθ(x t,t)) ">(3)pθ(xt−1∣xt):=N(xt−1;μθ(xt,t),Σθ(xt,t))
现在我们实际上已经简单了解了扩散模型的扩散过程和逆扩散过程。即在扩散过程中,人为地添加一点点噪声,直到数据变成纯高斯噪声;在逆扩散过程中,学习逆分布并逐渐恢复样本数据。
然而,马尔可夫过程中最麻烦的部分就是解决它。一般采用蒙特卡罗方法进行抽样,然后评价抽样结果的质量。上述扩散模型是否过于理想?
了解了逆扩散过程之后,现在是时候了解去噪推理过程了。但是如何训练扩散模型找到公式(3)中的平均值 μθ(xt, t) ">μθ(xt,t) 和方差 Σθ(x) t,t)">Σθ(xt,t)?
在VAE中,我们学习了最大似然估计的作用:对于已知的真实训练样本数据,并且需要模型的参数,可以使用最大似然估计。扩散模型使用最大似然估计来查找反向扩散过程中马尔可夫链转移的概率分布。这就是扩散模型的训练目的。也就是说,最大化模型预测分布的对数似然:
(4)L=Eq[− logpθ ( x0)]">(4)L=Eq[−logpθ(x0)]
对于神经网络模型来说,一般的优化方法是通过损失函数求解网络模型的最小值。最大化期望并不容易。所以另一种思路是求模型的最大似然估计,相当于求解使负对数似然最小化的变分上限 Lvlb"> Lvlb(变分上限):
(5)E[−log pθ(x0)] ≤Eq[−logpθ(x0:T)q(x1:T ∣x0)]=: Lvlb">(5)E[−logpθ(x0)]≤Eq[−logpθ(x0:T)q( x1: T∣x0)]=:Lvlb
因为变分上界很难求,但正如VAE推导中介绍的,上界其实可以用KL散度来表示。现在就是这样,最小化Lvlb> Lvlb 可以最大限度地减少扩散模型的目标损失。
什么是KL散度?
我们回顾一下,KL散度是一种非对称统计距离测度,衡量一个概率分布P与另一个概率分布Q之间的差异程度。我之所以想基于KL散度来求解L vlb">Lvlb ,因为根据Diffusion Models的定义,马尔可夫链中的传递分布属于高斯分布,并且KL 散度可用于计算两个高斯分布之间的差值距离。
连续分布的KL散度的数学形式为:
(6)DKL(P》 Q)=∫− ∞∞p(x) log(p(x) )q(x))d x">(6)DKL(P‖Q)= ∫− Infinityp(x)log(p(x)q(x))dx
用KL散度来表示变分上限
根据Diffusion Models最初提出的一篇文章[1],进一步分析Lvlb ">Lvlb 求导,我们可以得到 变异的上限是熵和多个KL散度的累加,根据KL散度改写变异的上限为:
(7)Lvlb=L0+L1+…+ LT−1+LT> (7)Lvlb=L0+L1+…+LT−1+LT
其中:
(8)L0=−logp θ(x0∣x 1)">(8)L0=−logpθ(x0∣x1)
(9)Lt−1=DK L(q( x t−1∣xt,x )‖pθ(xt−1∣xt) ) ">(9)Lt−1=DKL(q( xt −1∣xt,x0)‖pθ(xt−1∣xt))
(10)LT=DKL (q(x T ∣x0)‖p(x T))">( 10 )LT=DKL(q(xT∣x0)‖p(xT))
x0">x0Lt −1">Lt−1,现在所有 KL 散度都在高斯概率分布之间进行比较。这意味着可以使用闭包表达式而不是采样蒙特卡罗估计来准确计算变分上限。
这里听不懂也没关系,我想表达的是尽量减少Lvlb ">Lvlb最小化扩散模型目标损失,同时解决Lvlb"> Lvlb 可以通过计算KL散度来替换。
有了目标函数的数学基础之后,我们现在需要了解如何实现扩散模型训练过程的几个细节:
既然有神经网络模型,自然就离不开损失函数。有了损失函数,就有了优化的方向和目标。让我们扩展一下损失函数的定义。
在扩散过程公式(1)中,其中β1,…,βT">β1,…,βT 是高斯分布方差的超参数。实际上 βt">βt As t 增加是增加,即 β1 <…<βT>β1<…<βT . 在实际代码中,我们设置 βt ">βt 是从 0.0001 到 0.02 的线性插值。
在逆扩散过程公式(10)中,在时间步T中,由于前向扩散过程中q没有可学习的参数,因此简单地添加高斯噪声,在最后一个步骤T。T">xT是纯高斯噪声,所以在训练过程中LT">LT可以作为常数被忽略。即不需要下面的公式:
LT=DKL( q(xT∣x0)‖p(xT)):=0">LT= DKL (q(xT∣x0)‖p(xT)):=0 回忆一下公式(3),将逆马尔可夫过程转化为高斯分布来表示:(3)pθ(xt− ∣xt) : =N(xt−1;μ θ(xt ,t),Σθ(x t,t)) ">(3)pθ(xt−1∣xt):=N(xt−1;μθ(xt,t),Σθ(xt,t)) 在求解(训练)的过程中,需要知道高斯分布的均值μθ(xt ,t )">μθ(xt,t) 和方差 Σθ (xt,t)">Σθ(xt,t)。对于方差Σ">Σ很难求解,DDPM论文直接使用βt">βt而是:
回忆一下公式(3),将逆马尔可夫过程转化为高斯分布来表示:
在求解(训练)的过程中,需要知道高斯分布的均值μθ(xt ,t )">μθ(xt,t) 和方差 Σθ (
(11)Σθ(xt, t)=σ t 2Iσt2=βt>( 11 )Σθ(xt,t)=σt2Iσt2=βt
假设多元高斯是具有相同方差的独立高斯的乘积,则方差值可以随时间变化。基于这一假设,可以将反向扩散过程的方差设置为与正向扩散过程的方差相同,得到式(11)。不过有趣的是,在实际代码中,因为引入了神经网络,可以通过训练得到方差Σ">Σ.
数学上,假设使用 βt">βt 来替换方差 Σθ">Σθ,所以我们有:
(12)pθ(xt− ∣xt) : =N(xt−1;μ θ(xt ,t),Σθ(x t,t):= N(xt−1;μ θ(xt,t ),σt2I)"> (12)pθ(xt−1∣xt):=N( xt−1 ;μθ(xt,t),Σθ(xt,t):=N(xt−1;μθ(xt,t),σt2I)
现在更清楚了,可以发散KL:
(13)Lt−1=DK L(q( x t−1∣xt,x )‖pθ(xt−1∣xt) ) ">(13)Lt−1=DKL(q( xt −1∣xt,x0)‖pθ(xt−1∣xt))
转换为:
(14)Lt−1∝μ~t(xt ,x0)−μθ( xt,t)‖2">(14)Lt−1∝‖μ~t(xt,x0)−μθ(xt,t)‖2
从前向扩散过程中我们知道,任意时刻的xt">xt」可以由下式给出: x0"> x0和β">β代表。参数μθ ">μθ 最直接的表达是预测扩散模型后验概率的平均值。然而,在实际测试中,DDPM作者发现,训练预测任意给定时间步t的噪声分量μθ">μθ都会产生更好的结果。假设:
(15)μθ(xt, t)= * x α¯tϵθ (xt,t))
这样就可以得到损失函数L,让训练更加稳定:
(17)L简单 (θ) :=E,.0+1−α¯tϵ,t])(17)Lsimple (θ):=Et,x0,ϵ[‖ϵ−ϵθ (α tx0+1−α t ϵ,t) ‖2]
高斯分布ϵ">ϵ是神经网络模型预测的噪声(用于去噪),可以看作 ϵ(xt,t) ">ϵθ(xt,t)。扩散模型训练的核心是学习高斯噪声.
如上所述,在逆扩散过程中,马尔可夫过程被表示为连续条件高斯分布下的累积变换。有了整体的优化策略,我们还需要看看每个像素点的计算方式。在逆扩散过程结束时,我们希望得到生成的图像,因此我们需要设计一种方法,使得图像上的每个像素值满足离散对数似然。
为了实现这一目标,反扩散过程中的最终值从x1">x1更改为x0">x0 将设置转换为独立的离散计算。即在最后一个转换过程中,在给定的x_1$下得到图像x0"> 满足对数相似度,但假设像素之间是相互独立的: (18)pθ(x0∣x1 )=∏i= 1Dpθ(x0i∣ x1i)">(18 )pθ(x0∣x1)=∏i=1Dpθ(x0i∣x1i) 式(18)中,D为输入数据的维度,上标i表示图像中的坐标位置。现在的目标是确定给定像素的值有多大可能性,即我们想知道在相应时间步t=1时噪声图像x中相应像素值的分布: (19)N(x;μθi(x1,1) ,σ12)">(19)N(x;μθi(x1,1),σ12) t = 1 的像素分布来自多元高斯分布,其对角协方差矩阵允许我们将分布拆分为单变量高斯的乘积:(20)N(x;μθ(x1,1), σ12I)=∏i= DN(x;μθi(x1,1) ,σ12)">(20) N (x;μθ(x1,1),σ12I)=∏i=1DN(x;μθi(x1,1),σ12) 现在假设图像已标准化为 0-255 之间的值,范围为 [-1,1]。给定t=0时每个像素点的像素值,pθ(x0∣x )的值)">pθ(x0∣x1)是每个像素值的乘积。简而言之,这个过程可以用方程(18)简洁地表示:(21)pθ(x0∣x )= θ (x 0i∣x1i)i= (x0i)δ+( x x1,1) )d x">(21)pθ(x0∣x1)= ∏i =1Dpθ(x0i∣x1i)=∏i=1D∫δ−(x0i)δ+ (xii)N(x;μθi(x1,1),σ12)dx
(18)pθ(x0∣x1 )=∏i= 1Dpθ(x0i∣ x1i)">(18 )pθ(x0∣x1)=∏i=1Dpθ(x0i∣x1i)
式(18)中,D为输入数据的维度,上标i表示图像中的坐标位置。现在的目标是确定给定像素的值有多大可能性,即我们想知道在相应时间步t=1时噪声图像x中相应像素值的分布:
(19)N(x;μθi(x1,1) ,σ12)">(19)N(x;μθi(x1,1),σ12)
t = 1 的像素分布来自多元高斯分布,其对角协方差矩阵允许我们将分布拆分为单变量高斯的乘积:
(20)N(x;μθ(x1,1), σ12I)=∏i= DN(x;μθi(x1,1) ,σ12)">(20) N (x;μθ(x1,1),σ12I)=∏i=1DN(x;μθi(x1,1),σ12)
现在假设图像已标准化为 0-255 之间的值,范围为 [-1,1]。给定t=0时每个像素点的像素值,pθ(x0∣x )的值)">pθ(x0∣x1)是每个像素值的乘积。简而言之,这个过程可以用方程(18)简洁地表示:
(21)pθ(x0∣x )= θ (x 0i∣x1i)i= (x0i)δ+( x x1,1) )d x">(21)pθ(x0∣x1)= ∏i =1Dpθ(x0i∣x1i)=∏i=1D∫δ−(x0i)δ+ (xii)N(x;μθi(x1,1),σ12)dx
限制中:
δ−(x)={−= −1x−1255x>−1>x(x)={∞x= −1x−1255x>−1
和:
现在我们可以计算公式(8)中的最终转换概率分布 pθ(x0∣ x1)" >pθ(x0∣x1)的值。
训练过程如图左所示。算法1训练部分:
测试(采样)如右图算法2采样部分:
虽然上面一系列非常复杂或者难以理解的公式实际上是用来求得损失函数,或者是用来知道Diffusion Model的优化目标的。简化损失函数后,目标变简单了,主要是训练模型ϵθ">ϵθ。但是看了很多文章,还是停留在复杂的数学上.公式推导,Diffusion Model的网络模型结构还没有定义。
在定义网络模型之前,再次声明一下,Diffusion Model中模型的唯一要求是输入和输出数据维度dims需要相同。有点有趣。当你看到这句话时,你可能会想到类似U-Net的模型架构,而不是VAE的Encoder和Decoder压缩Latency sapce的结构。
在扩散过程公式(1)中,其中β1,…,βT">β1,…,βT 是高斯分布方差的超参数。实际上 βt">βt As t 增加是增加,即 β1 <…<βT>β1<…<βT . 在下面的实际代码中,我们使用 numpy 来设置 βt">βt是从0.0001到0.02的线性插值linspace,然后转换为称为Pytroch的张量。对应时间步长T,即num_steps设置为1000。
回顾一下扩散过程的公式(1):
为了表达方便,假设αt=1−β t ">αt=1−βt ,和 ὰt=∏s= 1tαs"> α¯ t=∏s=1tαs ,那么我们有:
(22)q(xt∣x0)=N( x 1t;α¯txt −1,(1−α ̀t)I)">(22 )q(xt∣x0)=N(xt;α ́txt−1,(1 −α ́t)I)
所以代码中的alpha对应于αt">αt,alphas_prod对应于ὰt》 >ὰt。然后首先计算式(22)中的变量。
num_steps = 1000 beta = torch.tensor(np.linspace(1e-5, 0.2e-2, num_steps)) 阿尔法 = 1 - 贝塔 alphas_prod = torch.cumprod(alphas, 0) alphas_prod_p = www.sychzs.cn([torch.tensor([1]).float(), alphas_prod[:-1]], 0) alphas_bar_sqrt = torch.sqrt(alphas_prod)one_minus_alphas_bar_log = torch.log(1 - alphas_prod) one_minus_alphas_bar_sqrt = torch.sqrt(1 - alphas_prod)
现在式(22)中有变量,q(x1:T ∣x0)” >q(x1:T∣x0)的函数表示变得比较简单,直接用下面的函数q_x来表示即可。
def q_x(x_0, t, 噪声=无): 如果不是噪音:噪音= torch.randn_like(x_0) alphas_t = 提取(alphas_bar_sqrt, t, x_0) alphas_1_m_t = 提取(one_minus_alphas_bar_sqrt, t, x_0) 返回(alphas_t * x_0 + alphas_1_m_t * 噪声)
前向过程的形式化计算相对简单明了。正如上面理论部分提到的,在每次马尔可夫链转换过程中,通过时间步T将噪声添加到样本数据集中:
对于范围内的 i(num_steps): q_i = q_x(数据集, torch.tensor([i]))
对应公式解q(xt∣ x0)">q(xt∣x0) 是:
posterior_mean_coef_1 = (betas * torch.sqrt(alphas_prod_p) / (1 - alphas_prod))terior_mean_coef_2 = ((1 - alphas_prod_p) * torch.sqrt(alphas) / (1 - alphas_prod)) 后验方差 = betas * (1 - alphas_prod_p) / (1 - alphas_prod) terior_log_variance_clipped = torch.log(www.sychzs.cn((posterior_variance[1].view(1, 1),terior_variance[1:].view(-1, 1)), 0)).view(-1) def q_posterior_mean_variance(x_0, x_t, t): coef_1 = 提取物(posterior_mean_coef_1, t, x_0) coef_2 = 提取物(posterior_mean_coef_2, t, x_0) 平均值 = coef_1 * x_0 + coef_2 * x_t var = extract(posterior_log_variance_clipped, t, x_0) 返回平均值,var
与正向扩散过程不同,反向扩散过程需要训练神经网络模型。这里,定义损失函数和训练参数,然后进行训练。
损失函数刚才在原理部分讨论过。通过最小化数据的负对数似然的变分上限来求解,即对应的公式(17)。网络模型直接使用Unet,这里不需要写Unet。互联网上有很多这样的内容。
来自模型导入Unet 从 EMA 导入 EMA 导入 torch.optim 作为 optim 模型 = Unet() 优化器 = optim.Adam(model.parameters(), lr=1e-3) # 创建 EMA 模型 EMA = EMA(0.9) ema.register(模型) # 批量大小批量大小 = 128 对于范围内的 t(num_steps): # X 是火炬变量 排列 = torch.randperm(dataset.size()[0]) 对于范围内的 i(0,dataset.size()[0],batch_size): #获取当前批次 索引 = 排列[i:i+batch_size] batch_x = 数据集[索引] # 计算损失。 损失=噪声估计损失(模型,batch_x,alphas_bar_sqrt,one_minus_alphas_bar_sqrt,num_steps) # 在向后传递之前,将所有网络梯度归零 优化器.zero_grad() # 向后传递:计算损失相对于参数的梯度 loss.backward() # 执行梯度裁剪 torch.nn.utils.clip_grad_norm_(model.parameters(), 1.) # 调用step函数更新参数 优化器.step() # 更新指数移动平均线 ema.更新(模型) # 打印损失 如果(t%100==0): 打印(丢失)
参考公式(17)的实现损失函数,在上述训练过程中没有进行扩展。下面给出一个简单的代码示例。当我有时间的时候我会详细解释它。今天我肚子疼,所以今天就到此为止了。
defnoise_estimation_loss(模型,x_0,alphas_bar_sqrt,one_minus_alphas_bar_sqrt,n_steps): 批量大小 = x_0.shape[0] # 为每个示例选择一个随机步骤 t = torch.randint(0, n_steps, size=(batch_size // 2 + 1,)) t = www.sychzs.cn([t, n_steps - t - 1], dim=0)[:batch_size].long() # x0 multiplier a = extract(alphas_bar_sqrt, t, x_0) # eps multiplier am1 = extract(one_minus_alphas_bar_sqrt, t, x_0) e = torch.randn_like(x_0) # model input x = x_0 * a + e * am1 output = model(x, t) return (e - output).square().mean()
学习 Diffusion Model 的过程当中,很容易陷入具体的数学细节,像我这样一看到数学就头痛的同学直接劝退,有些喜欢数学的同学则是不能自拔。下面总结一些 Diffusion Model 的要点。
[1] Deep Unsupervised Learning using Nonequilibrium Thermodynamics
[2] Generative Modeling by Estimating Gradients of the Data Distribution
[3] Denoising Diffusion Probabilistic Models
[4] Improved Techniques for Training Score-Based Generative Models
[5] Improved Denoising Diffusion Probabilistic Models
[6] Diffusion Models Beat GANs on Image Synthesis
[7] GLIDE: Towards Photorealistic Image Generation and Editing with Text-Guided Diffusion Models
[8] Hierarchical Text-Conditional Image Generation with CLIP Latents
[9] Introduction to Diffusion Models for Machine Learning
[10] diffusion-models-made-easy
[11] denoising-diffusion-model · GitHub