[AIGC] Vision Generative Models

72 阅读7分钟

一、简介

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

二、模型

2.1 GAN

Generative adversarial networks

GAN的主要结构包括一个生成器G(Generator)和一个判别器D(Discriminator);整个训练过程,便是二者的对抗博弈:给定 pdata(x)p_{data}(x),希望学习出G、D使得 pg=pdatap_g = p_{data} ,以至于D无法对二者进行正确分辨。

有如下缺点:

  • 训练不稳定,不容易收敛。

  • 容易出现模型坍缩(Mode Collapse),生成器总是生成相同的样本。

  • 生成过程不可控。

  • 不具备可解释性, pgp_g没有显式的表达。

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\alpha_t = 1 - \beta_tϵt\epsilon_t为第 t 步添加的噪音,则

xt=αtxt1+1αtϵtx_t=\sqrt{\alpha_t}x_{t-1}+\sqrt{1-\alpha_t}\epsilon_t (1)

xt1=αt1xt2+1αt1ϵt1x_{t-1}=\sqrt{\alpha_{t-1}}x_{t-2}+\sqrt{1-\alpha_{t-1}}\epsilon_{t-1} (2)

(2)带入(1),可得:

xt=αt(αt1xt2+1αt1ϵt1)+1αtϵt    =αtαt1xt2+(αt(1αt1)ϵt1+1αtϵt)   =αtαt1xt2+1αtαt1ϵtϵt1x_t=\sqrt{\alpha_t}({\sqrt{\alpha_{t-1}}x_{t-2}+\sqrt{1-\alpha_{t-1}}\epsilon_{t-1}})+\sqrt{1-\alpha_t}\epsilon_t \\   =\sqrt{\alpha_t}\sqrt{\alpha_{t-1}}x_{t-2}+(\sqrt{\alpha_t(1-\alpha_{t-1})}\epsilon_{t-1}+\sqrt{1-\alpha_t}\epsilon_t)\\     =\sqrt{\alpha_t}\sqrt{\alpha_{t-1}}x_{t-2}+\sqrt{1-\alpha_t\alpha_{t-1}}\epsilon_t\epsilon_{t-1}

其中化简利用了每次加入的噪声都服从高斯分布 ϵ1,ϵ2, ...   N(0,I)\epsilon_1, \epsilon_2, ... ~ N(0, I),相加后仍然服从高斯分布

N(0,σ12I)+N(0,σ22I)  N(0,(σ12+σ22)I)N(0, \sigma_1^2I)+N(0,\sigma_2^2I) \sim N(0,(\sigma_1^2+\sigma_2^2)I)

继续迭代,利用数学归纳法可得:

xt=αtx0+1αtϵtx_t=\sqrt{\overline{\alpha}_t}x_0+\sqrt{1-\overline{\alpha}_t}\overline{\epsilon}_t

以上公式表明,任意时刻的分布都可以通过 x0x_0 初始状态算出来,一步到位。

逆向过程(去噪)

利用贝叶斯公式求解逆向过程的噪音分布:

q(xt1xt,x0)=q(xtxt1,x0)q(xt1x0)q(xtx0)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(xt1x0): αt1x0+1αt1ϵ  N(αt1x0, 1αt1)q(x_{t-1}|x_0): \sqrt{\overline{\alpha}_{t-1}}x_0+\sqrt{1-\overline{\alpha}_{t-1}}\epsilon \sim N(\sqrt{\overline{\alpha}_{t-1}}x_0, 1-\overline{\alpha}_{t-1} )

q(xtx0): αtx0+1αtϵ  N(αtx0, 1αt)q(x_t|x_0): \sqrt{\overline{\alpha}_t}x_0+\sqrt{1-\overline{\alpha}_t}\epsilon \sim N(\sqrt{\overline{\alpha}_t}x_0, 1-\overline{\alpha}_t)

q(xtxt1, x0): αtxt1+1αtϵ  N(αtxt1, 1αt)q(x_t|x_{t-1}, x_0): \sqrt{\alpha_t}x_{t-1}+\sqrt{1-\alpha_t}\epsilon \sim N(\sqrt{\alpha_t}x_{t-1}, 1-\alpha_t)

列出分布如下(数学原理:多个标准正态分布展开之间的运算,乘法相当于加,除法相当于减)

q(xt1xt,x0)  exp(12((xtαtxt1)2βt+(xt1αt1x0)21αt1(xtαtx0)21αt))=exp(12((αtβt+11αt1)xt12(2αt11αt1x0)xt1+C(xt,x0)))q({x_{t-1}|x_t}, x_0) \propto exp(-\frac{1}{2}(\frac{(x_t-\sqrt{\alpha_t}x_{t-1})^2}{\beta_t}+\frac{(x_{t-1}-\sqrt{\overline{\alpha}_{t-1}}x_0)^2}{1-\overline{\alpha}_{t-1}}-\frac{(x_t-\sqrt{\overline{\alpha}_t}x_0)^2}{1-\overline{\alpha}_t}))\\=exp(-\frac{1}{2}((\frac{\alpha_t}{\beta_t}+\frac{1}{1-\overline{\alpha}_{t-1}})x^2_{t-1}-(\frac{2\sqrt{\overline{\alpha}_{t-1}}}{1-\overline{\alpha}_{t-1}}x_0)x_{t-1}+C(x_t, x_0)))

这个任务中,核心和 xt1x_{t-1}有关,所以以上的展开主要是在给 xt1x_{t-1} 配方,因为对于正态分布:

exp((xμ)22σ2)=exp(12(1σ2x22μσ2x+μ2σ2))exp(-\frac{(x-\mu)^2}{2\sigma^2})=exp(-\frac{1}{2}(\frac1{\sigma^2}x^2-\frac{2\mu}{\sigma^2}x+\frac{\mu^2}{\sigma^2}))

所以:

σq2(t)=(1αt)(1αt1)(1αt)\sigma^2_q(t)=\frac{(1-\alpha_t)(1-\overline{\alpha}_{t-1})}{(1-\overline{\alpha_t})}

μt(xt,x0)=αt(1αt1)1αtxt+αt1βt1αtx0\overline{\mu}_t(x_{t}, x_0)=\frac{\sqrt{\alpha_t}(1-\overline{\alpha}_{t-1})}{1-\overline{\alpha}_t}x_t+\frac{\sqrt{\overline{\alpha}_{t-1}}\beta_t}{1-\overline{\alpha}_t}x_0

上式中 x0x_{0}是未知的,这个时候就变成了鸡生蛋、蛋生鸡的问题。

模型训练目标

当一个概率分布q求解困难的时候,我们可以换个思路:通过人为构造一个新的分布 p,然后目标就转为缩小分布 p和q之间差距。通过不断修改p的参数去缩小差距,当 p和q足够相似的时候就可以替代q了

那么我们就构造一个高斯分布p(xt1xt)p(x_{t-1}|x_t)(见绿色箭头),让其方差和后验分布q(xt1xt,x0)q(x_{t-1}|x_t, x_0)一致:

然后缩小分布p(xt1xt)p(x_{t-1}|x_t)q(xt1xt,x0)q(x_{t-1}|x_t, x_0)之间差距,变成优化以下目标函数:

但是如果让模型直接从 xtx_t去预测 x0x_0,这个拟合难度太高了,再继续换个思路,由正向过程的结论可知

xt=αtx0+1αtϵtx_t=\sqrt{\overline{\alpha}_t}x_0+\sqrt{1-\overline{\alpha}_t}\overline{\epsilon}_t

由此式反向求 x0x_0,可得:

x0=xt1αtϵtαtx_0=\frac{x_t-\sqrt{1-\overline\alpha_t}\overline{\epsilon}_t}{\sqrt {\overline{\alpha}_t}}

带入上节中求出的均值公式中,可得

可以发现q(xt1xt,x0)q(x_{t-1}|x_t, x_0)的均值只和 xtx_t和前向扩散时候时间步 t 所加的噪声有关。

将模型改为去预测在前向时间步 t 所添加的高斯噪声 ϵ\epsilon,模型输入是 xtx_t和 时间步 t,预测结果为:

ϵ^θ(xt,t)\widehat\epsilon_\theta(x_t, t)

接着优化的目标函数就变为:

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

代码流程

Stable Diffusion Models 原理

  • ClipText:用于文本编码。

    • 输入: 文本。
    • 输出: 77 个token embeddings向量,每个向量有 768 维。
  • UNet + 调度程序: 在信息(潜在)空间中逐步处理信息。

    • 输入: 文本embeddings和一个初始化的多维数组(结构化的数字列表,也称为张量)组成的噪声。
    • 输出:经过处理的信息数组。
  • 自动编码解码器(Autoencoder Decoder): 使用经过处理的信息数组绘制最终图像。

    • 输入:经过处理的信息数组(维数:(4, 64, 64))

    • 输出: 生成的图像(维数:(3, 512, 512),即(红/绿/蓝;宽,高))。

Finetune相关技术

Dreambooth

方法的大致流程如下(其他的细节可参考原论文):

  1. 采集数据:包括少量的(如几张或几十张)某种狗的照片(比如你自己的狗)以及你自定义的提示词(比如狗的名字+"dog")也可以包含其他相关的描述,如照片中狗的动作,所在的场景等。

  2. 用自定义的样本对应的提示词输入给网络,生成图像,将对应的自定义图像作为真值计算loss。

  3. 将提示词中自定义的部分(比如狗的名字)去掉,只保留“dog”及其他描述,输入给原本预训练模型及finetune模型分别生成图像。

  4. 原本预训练模型输出的图像作为真值,和finetune模型生成的图像计算Prior-Preservation Loss,来约束finetune的过程,使finetune模型能保留原模型的能力。

LORA

Low-Rank Adaption of large language model

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

Controlnet

controlnet主要的功能是实现了对模型输入的条件控制。例如controlnet补齐了stable diffusion 条件控制这块短板,实现了人体姿势/图像边缘/深度图/语义色块图/法线图等多种方式对生成的图像进行精确控制。主要原理如下:

  1. 将我们需要修改的网络层复制一份,并在前后分别增加参数全为0的 卷积 ,作为右侧的 trainable分支。

  2. trainable分支的输出和原来的网络输出加在一起作为最终的输出。由于复制出来的网络前后的增加的卷积层参数均为0,输出也一定是0,因此整个网络的输出还和原来的网络完全一样。

  3. 在自己的数据集训练时将原来的网络固定只训练trainable的那个部分即可。

三、工程相关

开源社区

  • civitai:比较主流的AI绘画模型分享网站。可以看到大佬们跑出的图,并复现别人的tag或者下载别人finetune的模型。使用webui的时候这个网站用起来比较方便。

  • Huggingface:一个数据集、模型分享的网站,很多业界大牛也在使用和提交新模型,我们可以从stable diffusion 分区下载一些作者训练的模型。

  • stable diffusion(v1v2)。SD开源仓库,目前比较火的AI绘画大部分都是基于Stable Diffusion的。

  • stable-diffusion-webui: 这是目前大家最常用的工具,是一个基于Gradio库开发的浏览器UI界面,其后端依旧是Stable Diffusion以及一系列相关的工具包。其优点是操作简单,调参方便,方便分享模型,并且方便组合各种模块,非常适合广大没有相关基础的人使用。

  • diffusers:一个进行扩散模型训练、推理、Fine-Tuning的工具包。通过几行代码就可调用各种模块,比如stable dffusion,当然它还支持很多其他的扩散模型。

参考资料