一、简介
视觉生成模型主要包含以下几种类型:

二、模型
2.1 GAN
Generative adversarial networks

GAN的主要结构包括一个生成器G(Generator)和一个判别器D(Discriminator);整个训练过程,便是二者的对抗博弈:给定 pdata(x),希望学习出G、D使得 pg=pdata ,以至于D无法对二者进行正确分辨。
有如下缺点:
2.2 VAE Models
Variational AutoEncoders
AE
把一堆真实样本通过编码器网络变换成一个理想的数据分布,然后这个数据分布再传递给一个解码器网络,得到一堆生成样本,生成样本与真实样本足够接近的话,就训练出了一个自编码器(AE)网络。

局限性:
Eg: 如下图所示,我们用一张全月图和一张半月图去训练一个AE,经过训练,模型能够很好地还原出这两张图片。
但有如下问题:在latent code上两张图片编码点中间处任取一点进行解码,期望得到一张介于全月图和半月图之间的图片,实际还原出来的图片不仅模糊而且还是乱码的。

VAE
VAE(变分自编码器)就是在自编码器模型上做进一步变分处理,使得编码器 的输出结果能对应到目标分布的均值和方差


Eg:
解决方案:
- 引入噪声,扩大图片的编码区域,从而能够覆盖到失真的空白编码区。

- 将原先一个单点拉伸到整个编码空间,即将离散的编码点引申为一条连续的接近正态分布的编码曲线,如下所示:

2.3 Diffusion Models
Diffusion原理
正向过程(加噪)

噪音添加权重为 β,β越来越大,论文中从0.0001到0.002. 设 αt = 1 − βt, ϵt为第 t 步添加的噪音,则
xt=αtxt−1+1−αtϵt (1)
xt−1=αt−1xt−2+1−αt−1ϵt−1 (2)
(2)带入(1),可得:
xt=αt(αt−1xt−2+1−αt−1ϵt−1)+1−αtϵt =αtαt−1xt−2+(αt(1−αt−1)ϵt−1+1−αtϵt) =αtαt−1xt−2+1−αtαt−1ϵtϵt−1
其中化简利用了每次加入的噪声都服从高斯分布 ϵ1,ϵ2, ... N(0,I),相加后仍然服从高斯分布
N(0,σ12I)+N(0,σ22I) ∼ N(0,(σ12+σ22)I)
继续迭代,利用数学归纳法可得:
xt=αtx0+1−αtϵt
以上公式表明,任意时刻的分布都可以通过 x0 初始状态算出来,一步到位。
逆向过程(去噪)

利用贝叶斯公式求解逆向过程的噪音分布:
q(xt−1∣xt,x0)=q(xt∣xt−1,x0)q(xt∣x0)q(xt−1∣x0)
其中:
q(xt−1∣x0): αt−1x0+1−αt−1ϵ ∼ N(αt−1x0, 1−αt−1)
q(xt∣x0): αtx0+1−αtϵ ∼ N(αtx0, 1−αt)
q(xt∣xt−1, x0): αtxt−1+1−αtϵ ∼ N(αtxt−1, 1−αt)
列出分布如下(数学原理:多个标准正态分布展开之间的运算,乘法相当于加,除法相当于减)
q(xt−1∣xt,x0) ∝ exp(−21(βt(xt−αtxt−1)2+1−αt−1(xt−1−αt−1x0)2−1−αt(xt−αtx0)2))=exp(−21((βtαt+1−αt−11)xt−12−(1−αt−12αt−1x0)xt−1+C(xt,x0)))
这个任务中,核心和 xt−1有关,所以以上的展开主要是在给 xt−1配方,因为对于正态分布:
exp(−2σ2(x−μ)2)=exp(−21(σ21x2−σ22μx+σ2μ2))
所以:
σq2(t)=(1−αt)(1−αt)(1−αt−1)
μt(xt,x0)=1−αtαt(1−αt−1)xt+1−αtαt−1βtx0
上式中 x0是未知的,这个时候就变成了鸡生蛋、蛋生鸡的问题。
模型训练目标
当一个概率分布q求解困难的时候,我们可以换个思路:通过人为构造一个新的分布 p,然后目标就转为缩小分布 p和q之间差距。通过不断修改p的参数去缩小差距,当 p和q足够相似的时候就可以替代q了。
那么我们就构造一个高斯分布p(xt−1∣xt)(见绿色箭头),让其方差和后验分布q(xt−1∣xt,x0)一致:
然后缩小分布p(xt−1∣xt)和q(xt−1∣xt,x0)之间差距,变成优化以下目标函数:

但是如果让模型直接从 xt去预测 x0,这个拟合难度太高了,再继续换个思路,由正向过程的结论可知
xt=αtx0+1−αtϵt
由此式反向求 x0,可得:
x0=αtxt−1−αtϵt
带入上节中求出的均值公式中,可得

可以发现q(xt−1∣xt,x0)的均值只和 xt和前向扩散时候时间步 t 所加的噪声有关。
将模型改为去预测在前向时间步 t 所添加的高斯噪声 ϵ,模型输入是 xt和 时间步 t,预测结果为:
ϵθ(xt,t)
接着优化的目标函数就变为:

模型结构采用Unet,结构如下:

代码流程

Stable Diffusion Models 原理


Finetune相关技术
Dreambooth

方法的大致流程如下(其他的细节可参考原论文):
-
采集数据:包括少量的(如几张或几十张)某种狗的照片(比如你自己的狗)以及你自定义的提示词(比如狗的名字+"dog")也可以包含其他相关的描述,如照片中狗的动作,所在的场景等。
-
用自定义的样本对应的提示词输入给网络,生成图像,将对应的自定义图像作为真值计算loss。
-
将提示词中自定义的部分(比如狗的名字)去掉,只保留“dog”及其他描述,输入给原本预训练模型及finetune模型分别生成图像。
-
原本预训练模型输出的图像作为真值,和finetune模型生成的图像计算Prior-Preservation Loss,来约束finetune的过程,使finetune模型能保留原模型的能力。
LORA
Low-Rank Adaption of large language model

主要思路是在固定大网络的参数,并训练某些层(一般是某些层的线性部分,比如 Transformer中 的 QKV 的线性投影部分,以及 FFN 的线性部分)参数的增量,且这些参数增量可通过矩阵分解变成更少的可训练参数,大大降低 finetune 所需要训练的参数量。

Controlnet

controlnet主要的功能是实现了对模型输入的条件控制。例如controlnet补齐了stable diffusion 条件控制这块短板,实现了人体姿势/图像边缘/深度图/语义色块图/法线图等多种方式对生成的图像进行精确控制。主要原理如下:
-
将我们需要修改的网络层复制一份,并在前后分别增加参数全为0的 卷积 层,作为右侧的 trainable分支。
-
trainable分支的输出和原来的网络输出加在一起作为最终的输出。由于复制出来的网络前后的增加的卷积层参数均为0,输出也一定是0,因此整个网络的输出还和原来的网络完全一样。
-
在自己的数据集训练时将原来的网络固定,只训练trainable的那个部分即可。
三、工程相关
开源社区
-
civitai:比较主流的AI绘画模型分享网站。可以看到大佬们跑出的图,并复现别人的tag或者下载别人finetune的模型。使用webui的时候这个网站用起来比较方便。
-
Huggingface:一个数据集、模型分享的网站,很多业界大牛也在使用和提交新模型,我们可以从stable diffusion 分区下载一些作者训练的模型。
-
stable diffusion(v1,v2)。SD开源仓库,目前比较火的AI绘画大部分都是基于Stable Diffusion的。
-
stable-diffusion-webui: 这是目前大家最常用的工具,是一个基于Gradio库开发的浏览器UI界面,其后端依旧是Stable Diffusion以及一系列相关的工具包。其优点是操作简单,调参方便,方便分享模型,并且方便组合各种模块,非常适合广大没有相关基础的人使用。
-
diffusers:一个进行扩散模型训练、推理、Fine-Tuning的工具包。通过几行代码就可调用各种模块,比如stable dffusion,当然它还支持很多其他的扩散模型。
参考资料