Latent Diffusion Models在手写数字集的实现

694 阅读3分钟

回顾扩散模型

根据上次的结论,扩散模型可以视为一种带隐变量的生成模型,它的隐变量就是噪声。扩散模型有两个部分构成,分别是扩散还原

扩散过程对应图片到噪声的过程。首先从图片x0x_{0}到纯噪声xTx_T是一个长度为TT的马尔科夫链,如公式1;tt时刻的图片需要通过t1t-1时刻的图加噪得到(一阶马尔可夫链),如公式2;经过数学换算后,就可以将原始图片x0x_0直接映射到任意tt时刻的图xtx_{t}了,形式化表达如下,

q(x1:Tx0):=t=1Tq(xtxt1)                (1)q(xtxt1)=N(xt;1βtxt1,βtI)(2)q(xtx0)=N(xt;αtx0,(1αt)I)    (3)q(x_{1:T}|x_{0}):=\prod_{t=1}^{T}q(x_{t}|x_{t-1})\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (1)\\ q(x_t|x_{t-1})=\mathcal{N}(x_{t};\sqrt{1-\beta_{t}}x_{t-1},\beta_{t}I)(2)\\ q(x_t|x_0)=\mathcal{N}(x_t;\sqrt{\overline{\alpha_{t}}}x_{0},(1-\overline{\alpha_{t}})I)\ \ \ \ (3)\\

其中,αt\alpha_{t}是一个已知实数。

还原过程对应噪声图片去噪的过程。给定一张tt时刻的带噪声的图xtx_txt1x_{t-1}可以表示为xtx_{t}和添加噪声ϵ\epsilon的加权。如果我们可以预测噪声ϵ\epsilon,那我们就可以还原xt1x_{t-1},如公式4。噪声ϵ\epsilon的预测就用神经网络去做。从而,我们可以得到x0:Tx_{0:T}的联合分布,如公式5,进而积分得到原始图像x0x_{0}的分布,如公式6。

pθ(xt1xt):=N(xt1;μθ(xt,t),θ(xθ,t))           (4)pθ(x0:T):=p(xT))t=1Tpθ(xt1xt)                        (5)pθ(x0):=pθ(x0:T)dx1:T                                         (6)p_{\theta}(x_{t-1}|x_{t}):=\mathcal{N}(x_{t-1};\mu_{\theta}(x_t,t),\textstyle \sum_{\theta}(x_{\theta},t))\ \ \ \ \ \ \ \ \ \ \ (4)\\ p_{\theta}(x_{0:T}):=p(x_{T}))\prod_{t=1}^{T}p_{\theta}(x_{t-1}|x_{t})\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (5)\\ p_{\theta}(x_{0}):=\int p_{\theta}(x_{0:T})dx_{1:T}\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (6)

由于,公式6的积分比较难处理,我们采用变分估计E[logPθ(x0)]E[-logP_{\theta}(x_{0})]的下限。通过损失优化其下限,进而学习图像的分布。

带隐变量的扩散模型

扩散模型已经在图像修复、生成和多模态等方面取得了显著的成就。原始的扩散模型是像素级的(噪声需要和图像一般大),推理是费时费力的。进而,引入了带隐变量的扩散模型,如图1所示。**隐变量大小往往是远远小于图片大小的,因此减少了空间和时间的消耗。**注意,由于自动编码器编码了图像并没有理解图像内容的特征,即不同图像的编码之间没有语义联系,这里使用的是变分自动编码器,它可以学习图像的分布。

ldm模型图.png

图1 带隐变量的扩散模型

模型结构

考虑任务是生成手写数字,我们暂不考虑引入条件。由于变分自动编码器(VAE)可以学习图像的分布,我们使用VAE作为编码器和解码器。图1绿色框内的是一个简单的扩散模型。

实验过程

我们先定义一个变分自动编码器并在手写数字集上进行训练。

变分自动编码器.png

图2 变分自动编码器

输入是1通道,高28,宽28的图片,编码为4通道,高7,宽7的隐特征。 随便从正态分布中sample十个大小为(4, 7, 7)张量,解码看看效果。 我的妈.png

图3 生成效果图

生成效果很糟糕。看起来是采样到"奇异点"了,即不可映射到数字的点。sample了十个没有一个对应图,这说明隐变量的分布有些复杂。那我们调大平衡因子为0.1。

再重新训练后,同样操作,解码看看效果,看着正常多啦。

稍微正常点.png

图4 重新生成的效果图

我们得到了一个不错的编码器和解码器后,就可以用隐变量来训练扩散模型了,得到的就是Latent Diffusion Model,也就是将原来的图片转换为隐变量来加噪和去噪了。我们定义一个ldm模型,如图5所示。

ldm模型.png

图5 隐空间扩散模型

经过短暂训练后,我们可以得到一个隐空间扩散模型。那我们从正态分布中随机sample大小为(4, 7, 7)的张量作为隐变量,送给扩散模型进行去噪,这里设置去噪步骤共1000轮。我们记录最后901、最后801、···、最后1轮去噪后送给解码器的结果,如图6所示。

ldm模型结果.png

图6 潜空间扩散模型去噪效果

可以看到,一开始采样的不能称为隐变量,叫"奇异值"更合适了。慢慢的,经过不断去噪后,形成了一个正常的隐变量。

代码

完整数据和代码见我的github.

参考

[1] Coding Stable Diffusion from scratch in PyTorch - YouTube