前言

近两年 AI 发展非常迅速,其中的 AI 绘画也越来越火爆,AI 绘画在很多应用领域有巨大的潜力,AI 甚至能模仿各种著名艺术家的风格进行绘画。



目前比较有名商业化的 AI 绘画软件有 Midjourney、DALL·E2、以及百度出品的文心一格:https://yige.baidu.com/creation

但是他们都有一个共同点,那就是要钱。为了解决这个问题,我们可以自己做一款 AI 绘图软件。

本次分享主要涉及的内容:

  • 扩散模型(Diffusion Models)的原理
  • 扩散模型(Diffusion Models)的实践
  • Stable Diffusion 简单使用
  • Stable Diffusion 远端部署
  • 基于 Stable Diffusion 做一款属于自己的高质量 AI 绘图软件

【AIGC】图片生成的原理与应用现在主流的两个图像生成核心模型是 GAN 和 Diffusion Models。

生成对抗网络(Generative Adversarial Nets,GAN)于 2014 年提出,是一种基于对抗学习的深度生成模型,它由两个主要组件组成:生成器和判别器。生成器通过学习输入数据的分布,生成新的数据样本;判别器则尝试区分生成器生成的数据和真实数据。通过不断迭代训练,生成器和判别器相互对抗,最终生成器能够生成越来越逼真的数据。

扩散模型(Diffusion Models,DM) 于 2015 年被提出,在提出后的好多年中并没有掀起什么波澜,直到 2020 到 2022 年期间,基于该模型提出了其他改良模型如 DDPM、DDIM 等,扩散模型开始引起大量关注,2022 年 8 月基于扩散模型设计的 Stable Diffusion 出现后,扩散模型直接爆火。

扩散模型

扩散模型,像分子运动一样,一点点改变。对于图像而言,就是图像上的像素点一点点改变,直到最后改变成了有意义的图像。

不管是 GAN 模型还是 DM 模型,他们本质上都是给定输出 y 和输入 x,然后通过神经网络和深度学习建立两者的模式。

函数化

对于 AI 绘画,我们一般需要给出一个提示,让 AI 返回与提示匹配的图像,对于数学来说,我们则需要找到一个函数,让它能根据我们输入,转化成我们想要的输出。这个函数背后象征着一种模式,函数则依据这个模式来将我们的输入转化为输出。

那么怎么找到这个模式呢?

这就需要引入神经网络和深度学习了。

所谓的神经网络,其实都是由许多神经单元构成,而简单的神经单元,用数学公式表示的话,最基础,最简单的就是这样一个线性函数公式:
y = a x + b y = ax + b y=ax+b
有了这个简单的神经单元我们可以拟合一些数据的表现,比如下面这个图。

就像这个图,我们有一组数据(蓝色的点),然后我们用红线对应的函数表达了这组数据,虽然红线上的值和这组数据的分布点有差距,但差距不大,所以我们可以认为这个函数表达了这组数据的模式(学会了这组数据的模式)。

扩散模型的训练过程需要遵循监督学习的模式,它分为两个过程,分别是前向过程和后向过程。前向过程可以认为是生成输出 y 的过程,后向过程则是根据输入 x 输出对应 y 的训练过程。

扩散模型-前向过程

扩散模型的原论文链接:https://arxiv.org/pdf/2006.11239.pdf

前向过程,这个过程目的是生成一系列噪声,用于之后的后向过程训练,前向过程是不需要学习的。

我们先观察一下噪声分布,

大家觉得每个时刻加的噪音是一样的吗,一开始的时候加的多,还是后面加的多呢?

某个时刻的噪声跟哪个时刻最有关系呢?很明显当前时刻的噪声跟前一个时刻的噪声关系最密切,因为当前时刻的噪声可以用前一个时刻的噪声来求出,其实当前时刻的噪声和前一个时刻的噪声也只差了一个噪声而已。所以我们看第一个公式:
x t = a t x t − 1 + 1 − a t z 1 x_t = \sqrt{ {a}_t}x_{t-1} + \sqrt{1-{ {a}_t}}z_1 xt​=at​ ​xt−1​+1−at​ ​z1​

a t = 1 − β t a_t = 1 - β_t at​=1−βt​

这个公式里面,β 是一个常量,它的值从 0.0001 到 0.002。

现在我们已经能够求出各个时刻需要加的噪声是多少了,但是还有一个问题,就是我们每次计算当前时刻噪声的时候,都需要从 T0 时刻开始一直计算到 T 时刻,这个过程对前向过程可能没问题,也许只需要浪费一点内存保存前一个过程的噪声就行了,

但是扩散模型不止有前向过程,还有一个后向过程,后向过程其实就是根据当前噪声倒推前一个噪声是什么,所以后向过程只关心当前时刻的噪声,其他时刻的噪声并不关心,所以根据论文给出的原始公式,我们可以推导出一个公式:
x t = a ‾ t x 0 + 1 − a ‾ t z x_t = \sqrt{\overline{a}_t}x_0 + \sqrt{1-{\overline{a}_t}}z xt​=