当前位置:首页|资讯|Stable Diffusion

Stable Diffusion原理-第1部分

作者:吃玉米的大嘴怪发布时间:2023-11-02

最近做相关任务时,用到了stable diffusion,把这篇论文又拿出来看了一下,这里记录了一下笔记,文章顺序为:生成模型,VAE,层级VAE,扩散模型,  stable diffusion。

生成模型

生成模型的目标就是从一类图像中学习到它的分布,然后从得到的分布中进行采样就可以得到新的属于这一类的图像了,比如说你想要设计一个算法,让它可以生成猫的图像,那你就使用很多猫的图像进行学习,学习到猫这种图像的分布特性,然后从这个分布中进行采样,就可以得到新的猫的图像了。说起来简单,但是做起来却十分困难,因为猫的图像分布实在很复杂,再加上二维图像是高维的数据,我们很难对它使用参数进行直接建模,所以在生成模型里,经常会引入隐变量。

想像一下为什么会产生猫的图像,图像的产生可能跟猫的一些纹理和形状的特性是有关的,比如耳机尖尖,眼睛大大,有胡须之类的,总之背后有一些隐性的控制因素,我们将这些隐性的控制因素称为隐变量,这些隐性因素比我们观测到的结果简单,所以你可以用一个简单的分布去对它做假设。

p(z)(假设它是一个简单的分布,一般假设其服从标准正态分布), 想要训练一个函数(神经网络)得到p(x%7Cz),这样你从简单分布中进行采样,通过神经网络,可以得到相应的生成图像,但这个网络怎么训练呢?

图1

x,最大似然的优化目标是:

argmax%20%5C%20p(x)

考虑到隐变量,这个式子变为:

argmax%20%5Cint%20p(x%2Cz)%20dz

这里积分是很难积出来的,我们换一种表达方式:

%20log%20p(x)%5C%5C%0A%3D%5Cint%20%20log%20p(x%2Cz)%20dz%5C%5C%0A%3D%5Cint%20%20log%20p(x%2Cz)%20%5Cfrac%7Bq_%5Cphi(x%7Cz)%7D%7Bq_%5Cphi(x%7Cz)%7Ddz%5C%5C%0A%3DlogE_%7Bq_%5Cphi(z%7Cx)%7D(%5Cfrac%7Bp(x%2Cz)%7D%7Bq_%5Cphi(z%7Cx)%7D)%5C%5C%0A%5Cgeq%20%20E_%7Bq_%5Cphi(z%7Cx)%7D(log%5Cfrac%7Bp(x%2Cz)%7D%7Bq_%5Cphi(z%7Cx)%7D)%5C%5C%0A

q_%5Cphi(z%7Cx)表示从观测数据映射到隐变量空间的过程,这里最后一步用到了Jensen's 不等式,凹函数(log)的期望大于等到期望的凹函数。最后一项又称为evidence lower bound, ELBO。

log%20%5C%20p(x),可以通过近似最大化ELBO来实现。

%20E_%7Bq_%5Cphi(z%7Cx)%7D(log%5Cfrac%7Bp(x%2Cz)%7D%7Bq_%5Cphi(z%7Cx)%7D)%5C%5C%0A%3DE_%7Bq_%5Cphi(z%7Cx)%7Dlog%5Cfrac%7Bp(z)p_%5Ctheta(x%7Cz)%7D%7Bq_%5Cphi(z%7Cx)%7D%5C%5C%0A%3DE_%7Bq_%5Cphi(z%7Cx)%7Dlog%5Cfrac%7Bp(z)%7D%7Bq_%5Cphi(z%7Cx)%7D%2BE_%7Bq_%5Cphi(z%7Cx)%7D%7Bp_%5Ctheta(x%7Cz)%7D%5C%5C%0A%3D-KL(q_%5Cphi(z%7Cx)%7C%7Cp(z))%2BE_%7Bq_%5Cphi(z%7Cx)%7D%7Bp_%5Ctheta(x%7Cz)%7D

p_%5Ctheta(x%7Cz)表示从隐变量空间映射回数据真实分布的过程,ELBO通过推导分为了两项,第一项第称为先验匹配损失,第二步为重建损失,所以我们就把p(x)的最大似然变为了最大化这两项,推成这样有什么意义呢?因为这两项跟我们下面介绍的这个VAE网络是有关系的,这里p_%5Ctheta(x%7Cz)对应的是解码器,q_%5Cphi(z%7Cx)对应的是编码器。

VAE

VAE的总体结构如下:

p_%5Ctheta(x%7Cz),解码器对应q_%5Cphi(z%7Cx)部分,训练时,需要最小化前面提过的重建损失和最小先验匹配两部分。

先看第一项,最小重建损失:

x经过编码器之后映射到隐空间的z,然后能通过decoder恢复出来,使用一个损失函数的话,可以表达为:
z%3De(x)%5C%5C%0Aconstruction-loss%3D%7C%7Cd(z)-x%7C%7C_2

但是这样训练的话,会有些问题,因为我们现在训练的是一个生成模型,如果我们使用这个损失,网络只会学习到一些离散点的生成。

x映射到一个离散的隐变量点z, 然后解码器再将这个点重映回来,这使得离散点之间缺乏连续语义相关性,在非训练点采样时,无法采样得到有意义的东西,比较好的做法是,将输入x映射到某一个区间分布上,比如上图将满月的图片映射到某一个区间分布,将半月的图片映射到另一个区间分布,两个分布之间具有交叉,当采样点位于两个区间之间时,就知道我想采样的图片是一个既像半月又像满月的图片(可能是3/4月亮),这个技巧称为重参数化技巧,在VAE里面,区间分布我们用正态分布来表示。

x经过编码器之后得到u_x%5Csigma_x,这里u_x表示x映射到的正态区间分布的均值,%5Csigma_x为方差,这里涉及到的隐变量的维度你可以自己来定。

重参数化之后,重建损失可表示为:

u_x%2C%5Csigma_x%3De_%5Ctheta(x)%5C%5C%0Aloss-construction%3D%7C%7Cx-d_%5Cphi(u_x%2B%5Csigma_x%20%5Cepsilon)%7C%7C_2

再看第二项,先验匹配损失:

KL(q_%5Cphi(z%7Cx)%7C%7Cp(z)),从公式上理解就是,希望q_%5Cphi(z%7Cx)接近于先验分布p(z),先验分布通常使用标准正态分布p(z)%20%20%5Csim%20N(0%2CI),通过重参数化技巧,我们已经知道q_%5Cphi(z%7Cx)%20%5Csim%20N(u_x%2C%5Csigma_x)

p(z)%3D%5Cfrac%7B1%7D%7B%5Csqrt%20%7B2%5Cpi%7D%7De%5E%7B-%5Cfrac%7Bz%5E2%7D%7B2%7D%7D

q_%5Cphi(z%7Cx)%3D%5Cfrac%7B1%7D%7B%5Csqrt%20%7B2%20%5Cpi%7D%20%5Csigma_x%7De%5E%7B-%5Cfrac%7B(z-u_x)%5E2%7D%7B2%5Csigma_x%5E2%7D%7D

KL(q_%5Cphi(z%7Cx)%7C%7Cp(z))%5C%5C%0A%3D%5Cint_z%20q_%5Cphi(z%7Cx)log%5Cfrac%7Bq_%5Cphi(z%7Cx)%7D%7Bp(z)%7Ddz%5C%5C%0A%3D%5Cint_z%20%5Cfrac%7B1%7D%7B%5Csqrt%20%7B2%20%5Cpi%7D%20%5Csigma_x%7De%5E%7B-%5Cfrac%7B(z-u_x)%5E2%7D%7B2%5Csigma_x%5E2%7D%7D(-%5Cfrac%7B(z-u_x)%5E2%7D%7B2%5Csigma_x%5E2%7D-log%5Csigma_x%2B%5Cfrac%7Bz%5E2%7D%7B2%7D)dz%5C%5C%0A%3D-%5Cint_z%20%5Cfrac%7B1%7D%7B%5Csqrt%20%7B2%20%5Cpi%7D%20%5Csigma_x%7De%5E%7B-%5Cfrac%7B(z-u_x)%5E2%7D%7B2%5Csigma_x%5E2%7D%7D(%5Cfrac%7B(z-u_x)%5E2%7D%7B2%5Csigma_x%5E2%7D)dz-%5Cint_z%20%5Cfrac%7B1%7D%7B%5Csqrt%20%7B2%20%5Cpi%7D%20%5Csigma_x%7De%5E%7B-%5Cfrac%7B(z-u_x)%5E2%7D%7B2%5Csigma_x%5E2%7D%7Dlog%5Csigma_xdz%2B%5Cint_z%20%5Cfrac%7B1%7D%7B%5Csqrt%20%7B2%20%5Cpi%7D%20%5Csigma_x%7De%5E%7B-%5Cfrac%7B(z-u_x)%5E2%7D%7B2%5Csigma_x%5E2%7D%7D%5Cfrac%7Bz%5E2%7D%7B2%7Ddz%5C%5C%0A%3D-%5Cfrac%7B1%7D%7B2%5Csigma_x%5E2%7D%5Csigma_x%5E2-%5Cfrac%7B1%7D%7B2%7Dlog%5Csigma_x%5E2%2B%5Cfrac%7B1%7D%7B2%7D(u_x%5E2%2B%5Csigma_x%5E2)%5C%5C%0A%3D-%5Cfrac%7B1%7D%7B2%7D(1%2Blog%5Csigma_x%5E2-u_x%5E2-%5Csigma_x%5E2)

q_%5Cphi(x%7Cz)是高维的,但每个维度是独立的,推导方式一样,VAE的训练方式就是使用这两个损失函数对编码器与解码器进行训练, 训练好之后,进行采样时,就从隐变量空间p(z)%20%5Csim%20N(0%2CI)中随机进行采样,就可以得到生成的图片上。

层级VAE

VAE的方法可以产生还不错的生成结果,但是生成的结果并不是非常好,之后有人提出了层级VAE,层级VAE是什么呢?VAE里面我们不是用了两个神经网络,一个编码器,一个解码器,编码器将原始输入映射到隐变量空间,解码器将数据从隐变量空间进行恢复吗,但是可能一步映射到位方式并不是很合理,有时候这个映射函数太复杂,我们无法一步就能准确的进行映射。

x通过T步,一步一步映射到我们最终的隐变量z_T,其中间过程为z_1%20%5Csim%20z_%7BT-1%7D, 解码也是一点一点进行解码的,所以实际上在这个方法里,我们的观测变量是xz_1z_T都是隐变量。

我们将输入映射到最终隐变量空间的过程是一个马尔可夫链,因此这个方法又称为马尔可夫层级VAE, 马尔可夫链是什么呢,就是我们每一小步的映射都只跟前一次的结果有关,这个性质在计算联合分布时具有很好的特性,比如我想计算:

p(x%2Cz_1%2Cz_2%2Cz_3)%3Dp(x)p(z_1%7Cx)p(z_2%7Cx%2Cz_1)p(z_3%7Cx%2Cz_1%2Cz_2)

原始公式如上式所示,但如果它是马尔可夫过程,则这个公式可以简化为:

p(x%2Cz_1%2Cz_2%2Cz_3)%3Dp(x)p(z_1%7Cx)p(z_2%7Cz_1)p(z_3%7Cz_2)

我们在VAE里计算ELBO的结果套在HVAE(层级VAE)里,结果如下:

%20E_%7Bq_%5Cphi(z_1%3Az_T%7Cx)%7Dlog%5Cfrac%7Bp_%5Ctheta(x%2Cz_1%3Az_T)%7D%7Bq_%5Cphi(z_1%3Az_T%7Cx)%7D%5C%5C%0A%3DE_%7Bq_%5Cphi(z_1%3Az_T%7Cx)%7Dlog%5Cfrac%7Bp(z_T)p_%5Ctheta(x%7Cz_1)%5Cprod_%7Bt%3D2%7D%5E%7BT%7Dp_%5Ctheta(z_%7Bt-1%7D%7Cz_t)%7D%7Bq_%5Cphi(z_1%7Cx)%5Cprod_%7Bt%3D2%7D%5ETq_%5Cphi(z_t%7Cz_%7Bt-1%7D)%7D

具体的训练,这里不做介绍了,主要是用这个引出扩散模型。







Copyright © 2024 aigcdaily.cn  北京智识时代科技有限公司  版权所有  京ICP备2023006237号-1