Diffusion Model

整体思路

Diffusion Model的整体思路如下图所示:

image-20221217155738973

其主要分为正向过程和逆向过程,正向过程类似于编码,逆向过程类似于解码。

  • 正向过程

    首先,对于一张原始图片x0x_0x0​,我们给x0x_0x0​加一个高斯噪声,图片由x0x_0x0​变成x1x_1x1​。【注意:这里必须要加高斯噪声喔,因为高斯噪声服从高斯分布,后面的一些运算需要用到高斯分布的一些特性】接着我们会在x1x_1x1​的基础上再添加高斯噪声得到x2x_2x2​。重复上述添加高斯噪声步骤,直到图片变成xnx_nxn​,由于添加了足够多的高斯噪声,现在的xnx_nxn​近似服从高斯分布(又称正态分布)。

    现在有一个问题需要大家思考一下,我们每一步添加高斯噪声的量一直是不变的吗?🎅🏽🎅🏽🎅🏽滴,开始解答。答案是每步添加高斯噪声的量是变化的,且后一步比前一步添加的高斯噪声更多。我想这一点你通过上图也非常容易理解,一开始原图比较干净,我们添加少量高斯噪声就能对原图产生干扰;但越往后高斯噪声量越多,如果还添加一开始少量的高斯噪声,那么这时对上一步结果基本不会产生任何影响。【注:后文所述的每个时刻图像和这里的每一步图像都是一个意思,如x1x_1x1​时刻图像表示的就是x1x_1x1​这个图像】

  • 逆向过程

    首先,我们会随机生成一个服从高斯分布的噪声图片,然后一步一步的减少噪声直到生成预期图片。逆向过程大家先有这样的一个认识就好,具体细节稍后介绍。🌱🌱🌱

怎么样,大家现在的感觉如何?是不是知道了Diffusion Model大概是怎么样的过程了呢,但是又对里面的细节感到很迷惑,搞不懂这样是怎么还原出图片的。不用担心,后面我会慢慢为大家细细介绍。🥡🥡🥡

实施细节

  这一部分为大家介绍一下Diffusion Model正向过程和逆向过程的细节,主要通过推导一些公式来表示加噪前后图像间的关系,谈到公式,大家可能头都大了,相信我,你可以看懂!!!🥂🥂🥂

正向过程

  在整体思路部分我们已经知道了正向过程其实就是一个不断加噪的过程,于是我们考虑能不能用一些公式表示出加噪前后图像的关系呢。我想让大家先思考一下后一时刻的图像受哪些因素影响呢,更具体的说,比如x2x_2x2​由哪些量所决定呢?我想这个问题很简单,即x2x_2x2​是由x1x_1x1​和所加的噪声共同决定的,也就是说后一时刻的图像主要由两个量决定,其一是上一时刻图像,其二是所加噪声量。【这个很好理解,大家应该都能明白吧】明白了这点,我们就可以用一个公式来表示xtx_txt​时刻和xt−1x_{t-1}xt−1​时刻两个图像的关系,如下:

              Xt=atXt−1+1−atZ1{X_t} = \sqrt {{a_t}} {X_{t - 1}} + \sqrt {1 - {a_t}} {Z_1}Xt​=at​​Xt−1​+1−at​​Z1​     ——公式1

  其中,XtX_tXt​表示ttt时刻的图像,Xt−1X_{t-1}Xt−1​表示t−1t-1t−1时刻图像,Z1Z_1Z1​表示添加的高斯噪声,其服从N(0,1)分布。【注:N(0,1)表示标准高斯分布,其方差为1,均值为0】目前你可以看出XtX_tXt​和Xt−1X_{t-1}Xt−1​、Z1Z_1Z1​都有关系,这和我们前文所述后一时刻的图像由前一时刻图像和噪声决定相符合,这时你可能要问了,那么这个公式前面的at\sqrt {a_t}at​​和1−at\sqrt {1-a_t}1−at​​是什么呢,其实这个表示这两个量的权重大小,它们的平方和为1。

  enmmm,我想你已经明白了公式1,但是你可能对at\sqrt {a_t}at​​和1−at\sqrt {1-a_t}1−at​​的理解还存在一些疑惑,如为什么要设置这样的权重?这个权重的设置是我们预先设定的吗?🌶🌶🌶其实呢,ata_tat​还和另外一个量βt\beta_{t}βt​有关,关系式如下:

​              at=1−βta_t=1- \beta_tat​=1−βt​      ——公式2

  其中,βt\beta_tβt​是预先给定的值,它是一个随时刻不断增大的值,论文中它的范围为[0.0001,0.02]。既然βt\beta_tβt​越来越大,则ata_tat​越来越小,at\sqrt {a_t}at​​越来越小,1−at\sqrt {1-a_t}1−at​​越来越大。现在我们在来考虑公式1,Z1Z_1Z1​的权重1−at\sqrt {1-a_t}1−at​​随着时刻增加越来越大,表明我们所加的高斯噪声越来越多,这和我们整体思路部分所述是一致的,即越往后所加的噪声越多。🍄🍄🍄


  现在,我们已经得到了xtx_txt​时刻和xt−1x_{t-1}xt−1​时刻两个图像的关系,但是xt−1x_{t-1}xt−1​时刻的图像是未知的。【注:只有x0x_0x0​阶段图像是已知的,即原图】我们需要再由xt−2x_{t-2}xt−2​时刻推导出xt−1x_{t-1}xt−1​时刻图像,然后再由xt−3x_{t-3}xt−3​时刻推导出xt−2x_{t-2}xt−2​时刻图像,依此类推,直到由x0x_{0}x0​时刻推导出x1x_{1}x1​时刻图像即可。既然这样我们不妨先试试xt−2x_{t-2}xt−2​时刻图像和xt−1x_{t-1}xt−1​时刻图像的关系,如下:

​             Xt−1=at−1Xt−2+1−at−1Z2{X_{t-1}} = \sqrt {{{{a}}_{t-1}}} {X_{t - 2}} + \sqrt {1 - {{{a}}_{t-1}}} {Z_2}Xt−1​=at−1​​Xt−2​+1−at−1​​Z2​      ——公式3

这个公式很简单吧,就是公式1的一个类推公式,此时我们将公式3代入公式1中得:

​        Xt=at(at−1Xt−2+1−at−1Z2)+1−atZ1 =atat−1Xt−2+at(1−at−1)Z2+1−atZ1  =atat−1Xt−2+1−atat−1Z^2\begin{array}{l} {X_t} = \sqrt {{a_t}} (\sqrt {{a_{t - 1}}} {X_{t - 2}} + \sqrt {1 - {a_{t - 1}}} {Z_2}) + \sqrt {1 - {a_t}} {Z_1}\\ \quad \ {\rm{}} = \sqrt {{a_t}{a_{t - 1}}} {X_{t - 2}} + \sqrt {{a_t}(1 - {a_{t - 1}})} {Z_2} + \sqrt {1 - {a_t}} {Z_1}\\ \quad \ \ {\rm{ = }}\sqrt {{a_t}{a_{t - 1}}} {X_{t - 2}} + \sqrt {1 - {a_t}{a_{t - 1}}} {{\hat Z}_2} \end{array}Xt​=at​​(at−1​​Xt−2​+1−at−1​​Z2​)+1−at​​Z1​ =at​at−1​​Xt−2​+at​(1−at−1​)​Z2​+1−at​​Z1​  =at​at−1​​Xt−2​+1−at​at−1​​Z^2​​      ——公式4

这个公式4大家能理解吗?🌼🌼🌼我觉得大家应该对最后一个等式存在疑惑,也即at(1−at−1)Z2+1−atZ1\sqrt {{a_t}(1 - {a_{t - 1}})} {Z_2} + \sqrt {1 - {a_t}} {Z_1}at​(1−at−1​)​Z2​+1−at​​Z1​怎么等于1−atat−1Z^2\sqrt {1 - {a_t}{a_{t - 1}}} {{\hat Z}_2}1−at​at−1​​Z^2​ ?其实呢,这个用到了高斯分布的一些知识,这部分见附录部分,我做相关介绍。看了附录中高斯分布的相关性质,我想这里你应该能够理解了,我在帮大家整理一下,如下图所示:

image-20221219161141035

这下对于公式4的内容都明白了叭。注意这里的Z^2\hat Z_2Z^2​也是服从N(0,1)N(0,1)N(0,1)高斯分布的,at(1−at−1)Z2+1−atZ1\sqrt {{a_t}(1 - {a_{t - 1}})} {Z_2} + \sqrt {1 - {a_t}} {Z_1}at​(1−at−1​)​Z2​+1−at​​Z1​服从N(0,1−atat−1)N(0,1-a_ta_{t-1})N(0,1−at​at−1​)。我们来看看公式4得到了什么——其得到了xtx_txt​时刻图像和xt−2x_{t-2}xt−2​时刻图像的关系。按照我们先前的理解,我们再列出xt−3x_{t-3}xt−3​时刻图像和xt−2x_{t-2}xt−2​时刻图像的关系,如下:

​              Xt−2=at−2Xt−3+1−at−2Z3{X_{t-2}} = \sqrt {{{{a}}_{t-2}}} {X_{t - 3}} + \sqrt {1 - {{{a}}_{t-2}}} {Z_3}Xt−2​=at−2​​Xt−3​+1−at−2​​Z3​     ——公式5

同理,我们将公式5代入到公式4中,得到xtx_txt​时刻图像和xt−3x_{t-3}xt−3​时刻图像的关系,公式如下:

​            Xt=atat−1at−2Xt−3+1−atat−1at−2Z^3X_t=\sqrt {a_ta_{t-1}{a_{t-2}}}X_{t-3}+\sqrt {1-a_ta_{t-1}a_{t-2}}\hat Z_{3}Xt​=at​at−1​at−2​​Xt−3​+1−at​at−1​at−2​​Z^3​      ——公式6

  公式5我没有带大家一步步的计算了,只写出了最终结果,大家可以自己算一算,非常简单,也只用到了高斯分布的相关性质。注意上述的Z3^\hat {Z_3}Z3​^​同样服从N(0,1)N(0,1)N(0,1)的高斯分布。那么公式6就得到了xtx_txt​时刻图像和xt−3x_{t-3}xt−3​时刻图像的关系,我们如果这么一直计算下去,就会得到xtx_txt​时刻图像和x0x_{0}x0​时刻图像的关系。但是这样的推导貌似很漫长,随着向后推导你会发现这种推导是有规律的。我们可以来比较一下公式4和公式6的结果,你会发现很明显的规律,这里我就根据这个规律直接写出xtx_txt​时刻图像和x0x_{0}x0​时刻图像的关系,你看看和你想的是否一致喔,公式如下:

​              Xt=aˉtX0+1−aˉtZ^tX_t=\sqrt {{{\bar a}_t}} X_0+\sqrt {1-\bar a_t}\hat Z_tXt​=aˉt​​X0​+1−aˉt​​Z^t​      ——公式7

  其中aˉt\bar a_taˉt​表示累乘操作,即aˉt=at⋅at−1⋅at−2⋯a1{{\bar a}_t} = {a_t} \cdot {a_{t - 1}} \cdot {a_{t - 2}} \cdots {a_1}aˉt​=at​⋅at−1​⋅at−2​⋯a1​ ,Z^t\hat Z_tZ^t​同样服从N(0,1)N(0,1)N(0,1)的高斯分布。【这里Z^t\hat Z_tZ^t​只是一个表示,只要ZZZ服从标准高斯分布即可,用什么表示都行】这个公式7就是整个正向过程的核心公式喔,其表示xtx_txt​时刻的图像可以由x0x_0x0​时刻的图像和一个标准高斯噪声表示,大家需要牢记这个公式哦,在后文以及代码中会用到。🍈🍈🍈


逆向过程

  逆向过程是将高斯噪声还原为预期图片的过程。先来看看我们已知条件有什么,其实就一个xtx_txt​时刻的高斯噪声。我们希望将xtx_txt​时刻的高斯噪声变成x0x_0x0​时刻的图像,是很难一步到位的,因此我们思考能不能和正向过程一样,先考虑xtx_txt​时刻图像和xt−1x_{t-1}xt−1​时刻的关系,然后一步步向前推导得出结论呢。好的,思路有了,那就先来想想如何由已知的xtx_txt​时刻图像得到xt−1x_{t-1}xt−1​时刻图像叭。🥂🥂🥂

  有没有大佬想出怎么办呢?我就不卖关子了,要想由xtx_txt​时刻图像得到xt−1x_{t-1}xt−1​时刻图像,我们需要利用正向过程中的结论,我们在正向过程中可以由xt−1x_{t-1}xt−1​时刻图像得到xtx_{t}xt​时刻图像,然后利用贝叶斯公式即可求解。

  !!!???什么,贝叶斯公式,不知道大家是否了解。如果不知道的建议去学习一下概率的知识,如果实在也不想学,大家就记住贝叶斯公式的表达式即可,如下:

那么我们将利用贝叶斯公式来求xt−1x_{t-1}xt−1​时刻图像,公式如下:

​              q(Xt−1∣Xt)=q(Xt∣Xt−1)q(Xt−1)q(Xt)q({X_{t - 1}}|{X_t}) = q({X_t}|{X_{t - 1}})\frac{{q({X_{t - 1}})}}{{q({X_t})}}q(Xt−1​∣Xt​)=q(Xt​∣Xt−1​)q(Xt​)q(Xt−1​)​     ——公式8

  公式8中q(Xt∣Xt−1)q({X_t}|{X_{t - 1}})q(Xt​∣Xt−1​)我们可以求得,就是刚刚正向过程求的嘛。🍟🍟🍟但q(Xt−1)q(X_{t - 1})q(Xt−1​)和q(Xt)q(X_{t})q(Xt​)是未知的。又由公式7可知,可由X0X_0X0​得到每一时刻的图像,那当然可以得到XtX_tXt​和Xt−1X_{t-1}Xt−1​时刻的图像,故将公式8加一个X0X_0X0​作为已知条件,将公式8变成公式9,如下:

​            q(Xt−1∣Xt,X0)=q(Xt∣Xt−1,X0)q(Xt−1∣X0)q(Xt∣X0)q({X_{t - 1}}|{X_t},{X_0}) = q({X_t}|{X_{t - 1}},{X_0})\frac{{q({X_{t - 1}}|{X_0})}}{{q({X_t}|{X_0})}}q(Xt−1​∣Xt​,X0​)=q(Xt​∣Xt−1​,X0​)q(Xt​∣X0​)q(Xt−1​∣X0​)​     ——公式9

  现在可以发现公式9右边3项都是可以算的啦,我们列出它们的公式和对应的分布,如下图所示:

在这里插入图片描述

  知道了公式9等式右边3项服从的分布,我们就可以计算出等式左边的q(Xt−1∣Xt,X0)q({X_{t - 1}}|{X_t},{X_0})q(Xt−1​∣Xt​,X0​)。大家知道怎么计算嘛,这个很简单啦,没有什么技巧,就是纯算。在附录->高斯分布性质部分我们知道了高斯分布的表达式为:f(x)=12πσe−(x−u)22σ2f(x) = \frac{1}{{\sqrt {2\pi \sigma } }}{e^{ - \frac{{{{(x - u)}^2}}}{{2{\sigma ^2}}}}}f(x)=2πσ​1​e−2σ2(x−u)2​。那么我们只需要求出公式9等式右边3个高斯分布表达式,然后进行乘除运算即可求得q(Xt−1∣Xt,X0)q({X_{t - 1}}|{X_t},{X_0})q(Xt−1​∣Xt​,X0​)。

image-20221222144625338

  上图为等式右边三个高斯分布表达式,这个结果怎么得的大家应该都知道叭,就是把各自的均值和方差代入高斯分布表达式即可。现我们只需对上述三个式子进行对应乘除运算即可,如下图所示:

  好了,我们上图中得到了式子M⋅e−12[(αtβt+11−aˉt−1)Xt−12−(2aˉtβtXt+2aˉt−11−aˉt−1X0)Xt−1+C(Xt,X0)]M \cdot {e^{ - \frac{1}{2}[(\frac{{{\alpha _t}}}{{{\beta _t}}} + \frac{1}{{1 - {{\bar a}_{t - 1}}}})X_{t - 1}^2 - (\frac{{2\sqrt {{{\bar a}_t}} }}{{{\beta _t}}}{X_t} + \frac{{2\sqrt {{{\bar a}_{t - 1}}} }}{{1 - {{\bar a}_{t - 1}}}}{X_0}){X_{t - 1}} + C({X_t},{X_0})]}}M⋅e−21​[(βt​αt​​+1−aˉt−1​1​)Xt−12​−(βt​2aˉt​​​Xt​+1−aˉt−1​2aˉt−1​​​X0​)Xt−1​+C(Xt​,X0​)]其实就是q(Xt−1∣Xt)q({X_{t - 1}}|{X_t})q(Xt−1​∣Xt​)的表达式了。知道了这个表达式有什么用呢,主要是求出均值和方差。首先我们应该知道对高斯分布进行乘除运算的结果仍然是高斯分布,也就是说q(Xt−1∣Xt)q({X_{t - 1}}|{X_t})q(Xt−1​∣Xt​)服从高斯分布,那么他的表达式就为 f(x)=12πσe−(x−u)22σ2=12πσe−12[x2σ2−2uxσ2+u2σ2]f(x) = \frac{1}{{\sqrt {2\pi \sigma } }}{e^{ - \frac{{{{(x - u)}^2}}}{{2{\sigma ^2}}}}} = \frac{1}{{\sqrt {2\pi \sigma } }}{e^{ - \frac{1}{2}[\frac{{{x^2}}}{{{\sigma ^2}}} - \frac{{2ux}}{{{\sigma ^2}}} + \frac{{{u^2}}}{{{\sigma ^2}}}]}}f(x)=2πσ​1​e−2σ2(x−u)2​=2πσ​1​e−21​[σ2x2​−σ22ux​+σ2u2​],我们对比两个表达式,就可以计算出uuu和σ2\sigma^2σ2,如下图所示:

  现在我们有了均值uuu和方差σ2\sigma^2σ2就可以求出q(Xt−1∣Xt)q({X_{t - 1}}|{X_t})q(Xt−1​∣Xt​)了,也就是求得了xt−1x_{t-1}xt−1​时刻的图像。推导到这里不知道大家听懂了多少呢?其实你动动小手来算一算你会发现它还是很简单的。但是不知道大家有没有发现一个问题,我们刚刚求得的最终结果uuu和σ2\sigma^2σ2中含义一个X0X_0X0​,这个X0X_0X0​是什么啊,他是我们最后想要的结果,现在怎么当成已知量了呢?这一块确实有点奇怪,我们先来看看我们从哪里引入了X0X_0X0​。往上翻翻你会发现使用贝叶斯公式时我们利用了正向过程中推导的公式7来表示q(Xt−1)q(X_{t - 1})q(Xt−1​)和q(Xt)q(X_{t})q(Xt​),但是现在看来那个地方会引入一个新的未知量X0X_0X0​,该怎么办呢?这时我们考虑用公式7来反向估计X0X_0X0​,即反解公式7得出X0X_0X0​的表达式,如下:

​              X0=1aˉt(Xt−1−aˉtZ^t){X_0} = \frac{1}{{\sqrt {{{\bar a}_t}} }}({X_t} - \sqrt {1 - {{\bar a}_t}} {{\hat Z}_t})X0​=aˉt​​1​(Xt​−1−aˉt​​Z^t​)      ——公式10

得到X0X_0X0​的估计值,此时将公式10代入到上图的uuu中,计算后得到最后估计的 u~{\tilde u}u~,表达式如下:

​              u~=1at(xt−βt1−aˉtZ^t)\tilde u = \frac{1}{{\sqrt {{a_t}} }}({x_t} - \frac{{{\beta _t}}}{{\sqrt {1 - {{\bar a}_t}} }}{{\hat Z}_t})u~=at​​1​(xt​−1−aˉt​​βt​​Z^t​)      ——公式11

好了,现在在整理一下t−1t-1t−1时刻图像的均值uuu和方差σ2\sigma^2σ2,如下图所示:

image-20221222221914396

有了公式12我们就可以估计出Xt−1X_{t-1}Xt−1​时刻的图像了,接着就可以一步步求出Xt−2X_{t-2}Xt−2​、Xt−3X_{t-3}Xt−3​、X1X_1X1​、X0X_0X0​的图像啦。🍄🍄🍄🍄


原理小结

  这一小节原理详解部分就为大家介绍到这里了,大家听懂了多少呢。相信你阅读了此部分后,对Diffusion Model的原理其实已经有了哥大概的解了,但是肯定还有一些疑惑的地方,不用担心,代码部分会进一步帮助大家。🌸🌸🌸

   

Diffusion Model源码解析✨✨✨

代码下载及使用

  本次代码下载地址:Diffusion Model代码🚀🚀🚀

  先来说说代码的使用吧,代码其实包含两个项目,一个的ddpm.py,另一个是ddpm_condition.py。大家可以理解为ddpm.py是最简单的扩散模型,ddpm_condition.pyddpm.py的优化。本节会以ddpm.py为大家讲解。代码使用起来非常简单,首先在ddpm.py文件中指定数据集路径,即设置dataset_path的值,然后我们就可以运行代码了。需要注意的是,如果你使用的是CPU的话,那么你可能还需要修改一下代码中的device参数,这个就很简单啦,大家自己摸索摸索就能研究明白。


  这里来简单说说ddpm的意思,英文全称为Denoising Diffusion Probabilistic Model,中文译为去噪扩散概率模型。🍄🍄🍄


代码流程图

这里我们直接来看论文中给的流程图好了,如下:

image-20221231194352866

  看到这个图你大概率是懵逼的,我来稍稍为大家解释一下。首先这个图表示整个算法的流程分为了训练阶段(Training)和采样阶段(Sampling)。

  • Training

    我们先来看看训练阶段我们做了什么?众所周知,训练我们需要有真实值和预测值,那么对于本例的真实值和预测值是什么呢?真实值是我们输入的图片,预测值是我们输出的图片吗?其实不是,这里我就不和大家卖关子了。对于本例来说,真实值和预测值都是噪声,我们同样拿下图为大家做个示范。

    image-20221231195607326

    我们在正向过程中加入的噪声其实都是已知的,是可以作为真实值的。而逆向过程相当于一个去噪过程,我们用一个模型来预测噪声,让正向过程每一步加入的噪声和逆向过程对应步骤预测的噪声尽可能一致,而逆向过程预测噪声的方式就是丢入模型训练,其实就是Training中的第五步。

  • Sampling

    知道了训练过程,采样过程就很简单了,其实采样过程就对应我们理论部分介绍的逆向过程,由一个高斯噪声一步步向前迭代,最终得到X0X_0X0​时刻图像。

代码解析

  首先,按照我们理论部分应该有一个正向过程,其最重要的就是最后得出的公式7,如下:

Xt=aˉtX0+1−aˉtZ^tX_t=\sqrt {{{\bar a}_t}} X_0+\sqrt {1-\bar a_t}\hat Z_tXt​=aˉt​​X0​+1−aˉt​​Z^t​

  那么我们在代码中看一看是如何利用这个公式7的,代码如下:

 

python

复制代码

def noise_images(self, x, t): sqrt_alpha_hat = torch.sqrt(self.alpha_hat[t])[:, None, None, None] sqrt_one_minus_alpha_hat = torch.sqrt(1 - self.alpha_hat[t])[:, None, None, None] Ɛ = torch.randn_like(x) return sqrt_alpha_hat * x + sqrt_one_minus_alpha_hat * Ɛ, Ɛ

  Ɛ为随机的标准高斯分布,其实也就是真实值。大家可以看出,上式的返回值sqrt_alpha_hat * x + sqrt_one_minus_alpha_hat其实就表示公式7。【注:这个代码我省略了很多细节,我只把关键的代码展示给大家看,要想完全明白,还需要大家记住调试调试了】

  接着我们就通过一个模型预测噪声,如下:

 

python

复制代码

predicted_noise = model(x_t, t)

  model的结构很简单,就是一个Unet结构,然后里面嵌套了几个Transformer机制,我就不带大家跳进去慢慢看了。现在有了预测值,也有了真实值Ɛ【返回后Ɛ用noise表示】,就可以计算他们的损失并不断迭代了。

 

python

复制代码

loss = mse(noise, predicted_noise) optimizer.zero_grad() loss.backward() optimizer.step()


  上述其实就是训练过程的大体结构,我省略了很多,要是大家有任何问题的话可以评论区留言讨论。现在就来看看采样过程的代码吧!!!

 

python

复制代码

def sample(self, model, n): logging.info(f"Sampling {n} new images....") model.eval() with torch.no_grad(): x = torch.randn((n, 3, self.img_size, self.img_size)).to(self.device) # for i in tqdm(reversed(range(1, self.noise_steps)), position=0): for i in tqdm(reversed(range(1, 5)), position=0): t = (torch.ones(n) * i).long().to(self.device) predicted_noise = model(x, t) alpha = self.alpha[t][:, None, None, None] alpha_hat = self.alpha_hat[t][:, None, None, None] beta = self.beta[t][:, None, None, None] if i > 1: noise = torch.randn_like(x) else: noise = torch.zeros_like(x) x = 1 / torch.sqrt(alpha) * (x - ((1 - alpha) / (torch.sqrt(1 - alpha_hat))) * predicted_noise) + torch.sqrt(beta) * noise model.train() x = (x.clamp(-1, 1) + 1) / 2 x = (x * 255).type(torch.uint8) return x

  上述代码关键的就是 x = 1 / torch.sqrt(alpha) * (x - ((1 - alpha) / (torch.sqrt(1 - alpha_hat))) * predicted_noise) + torch.sqrt(beta) * noise这个公式,其对应着代码流程图中Sampling阶段中的第4步。需要注意一下这里的跟方差σt\sigma_tσt​这个公式给的是β\sqrt {\beta}β​,但其实在我们理论计算时为βt(1−aˉt−1)1−aˉt\sqrt {\frac{{{\beta _t}(1 - {{\bar a}_{t - 1}})}}{{1 - {{\bar a}_t}}}}1−aˉt​βt​(1−aˉt−1​)​​,这里做了近似处理计算,即aˉt−1{\bar a}_{t - 1}aˉt−1​和aˉt\bar a_taˉt​都是非常小且近似0的数,故把(1−aˉt−1)1−aˉt{\frac{{(1 - {{\bar a}_{t - 1}})}}{{1 - {{\bar a}_t}}}}1−aˉt​(1−aˉt−1​)​当成1计算,这里注意一下就好。🍵🍵🍵

代码小结

  可以看出,这一部分我所用的篇幅很少,只列出了关键的部分,很多细节需要大家自己感悟。比如代码中时刻T的用法,其实是较难理解的,代码中将其作为正余弦位置编码处理。如果你对位置编码不熟悉,可以看一下我的这篇文章的附录部分,有详细的介绍位置编码,相信你读后会有所收获。🌿🌿🌿

作者:秃头小苏
链接:https://juejin.cn/post/7210175991837507621
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值