前排提示照片已经获得小姐姐许可。
光知道ControlNet好用,不想知道它背后的原理么?今天就看一看这篇论文,带大家了解一下ControlNet是如何炼成的。
ControlNet是干嘛的
我们知道现在文本到图像生成很火爆,你只需要输入文字就可以获得对应的输出,这个任务的发展多亏了扩散模型的发展。
而我们今天要说的ControlNet的作用就是能够控制扩散模型,生成更接近用户需求的图。
我们用几个图示范一下:
假如我们只用文字去生成图像,我们给模型输入文本prompt:
a girl
, long hair
, blond hair
, black eyes
, black coat
, winter
, snow
。
那模型会出来这些图:
我们可以看到,我们输入的要素都符合了。但是差别又很大,大在哪里?每个妹子动作差异都好大。
那现在我们就可以掏出ControlNet了,用ControlNet来控制你生成的人物的动作。
比如下图这样,可以看到即使我换了画风(换了模型的checkpoint)生成的人物动作也是一样的, 并且满足我前边输入的条件。
那我做了什么才让模型能稳定输出相同的人物动作呢?下面请出我们的仙女姐姐尚尚:
为我们生成的妹子提供动作的是我们的尚影嫣小姐姐,我把她的照片放到ControlNet中作为控制条件,这里使用的是ControlNet的Depth功能,ControlNet会根据小姐姐提取一个深度图,然后按照人物深度图轮廓去生成我们的人物。
下图你看到的就是文本prompt控制和ControlNet图像条件控制相互作用的结果。
既符合文本prompt:a girl
, long hair
, blond hair
, black eyes
, black coat
, winter
, snow
,又保持了小姐姐的大致动作形态。
当然,如果我们把文字控制删除一点,只留下a girl
, long hair
, black eyes
,我们可以得到更接近小姐姐原图的结果。
好了,美女看完了,那我们就介绍一下这个论文吧。
ControlNet 网络设计
在一个扩散模型中,如果不加ControlNet的扩散模型,其中原始的神经网络F\mathcal FF输入xxx获得yyy,参数用Θ\ThetaΘ表示。
y=F(x;Θ)y = \mathcal F(x;\Theta)y=F(x;Θ)
也就是下图这个样子。
ControlNet中,就是将模型原始的神经网络锁定,设为locked copy。
然后将原始网络的模型复制一份,称之为trainable copy,在其上进行操作施加控制条件。然后将施加控制条件之后的结果和原来模型的结果相加获得最终的输出。
经过这么一顿操作之后,施加控制条件之后,最后将原始网络的输出修改为:
yc=F(x;Θ)+Z(F(x+Z(c;Θz1);Θc);Θz2)\boldsymbol{y}_{\mathrm{c}}=\mathcal{F}(\boldsymbol{x} ; \Theta)+\mathcal{Z}\left(\mathcal{F}\left(\boldsymbol{x}+\mathcal{Z}\left(\boldsymbol{c} ; \Theta_{\mathrm{z} 1}\right) ; \Theta_{\mathrm{c}}\right) ; \Theta_{\mathrm{z2}}\right)yc=F(x;Θ)+Z(F(x+Z(c;Θz1);Θc);Θz2)
其中zero convolution,也就是零卷积层Z\mathcal ZZ是初始化weight和bias为0,两层零卷积的参数为{Θz1,Θz2}\{ \Theta_{z1},\Theta_{z2} \}{Θz1,Θz2}。
将控制条件通过零卷积之后,与原始输入相加,相加之后进入ControlNet的复制神经网络块中,将网络输出再做一次零卷积之后与原始网络的输出相加。
初始化之后未经训练的ControlNet参数应该是这样的:
{Z(c;Θz1)=0F(x+Z(c;Θz1);Θc)=F(x;Θc)=F(x;Θ)Z(F(x+Z(c;Θz1);Θc);Θz2)=Z(F(x;Θc);Θz2)=0\left\{\begin{array}{l}\mathcal{Z}\left(\boldsymbol{c} ; \Theta_{\mathrm{z} 1}\right)=0 \\ \mathcal{F}\left(x+\mathcal{Z}\left(\boldsymbol{c} ; \Theta_{\mathrm{z} 1}\right) ; \Theta_{\mathrm{c}}\right)=\mathcal{F}\left(x ; \Theta_{\mathrm{c}}\right)=\mathcal{F}(x ; \Theta) \\ \mathcal{Z}\left(\mathcal{F}\left(x+\mathcal{Z}\left(\boldsymbol{c} ; \Theta_{\mathrm{z} 1}\right) ; \Theta_{\mathrm{c}}\right) ; \Theta_{\mathrm{z} 2}\right)=\mathcal{Z}\left(\mathcal{F}\left(x ; \Theta_{\mathrm{c}}\right) ; \Theta_{\mathrm{z} 2}\right)=\mathbf{0}\end{array}\right.⎩⎨⎧Z(c;Θz1)=0F(x+Z(c;Θz1);Θc)=F(x;Θc)=F(x;Θ)Z(F(x+Z(c;Θz1);Θc);Θz2)=Z(F(x;Θc);Θz2)=0
也就是说ControlNet未经训练的时候,输出为0,那加到原始网络上的数字也是0。这样对原始网络是没有任何影响的,就能确保原网络的性能得以完整保存。之后ControlNet训练也只是在原始网络上进行优化,这样可以认为和微调网络是一样的。
ControlNet in Stable Diffusion
上一部分描述了ControlNet如何控制单个神经网络块,论文中作者是以Stable Diffusion为例子,讲了如何使用ControlNet对大型网络进行控制。下图可以看到控制Stable Diffusion的过程就是将Encoder复制训练,decoder部分进行skip connection。
在这之前需要注意:
Stable Diffusion有一个预处理步骤,将512×512的图片转化为64×64的图之后再进行训练,因此为了保证将控制条件也转化到64×64的条件空间上,训练过程中添加了一个小网络E\EpsilonE将图像空间条件转化为特征图条件。
cf=E(ci)c_f = \Epsilon (c_i)cf=E(ci)
这个网络E\EpsilonE是四层卷积神经网络,卷积核为4×4,步长为2,通道16,32,64,128,初始化为高斯权重。这个网络训练过程是和整个ControlNet进行联合训练。
或者我们可以把他的图改吧改吧,画成这样:
训练过程
训练的目标函数为:
L=Ez0,t,ct,cr,ϵ∼N(0,1)[∥ϵ−ϵθ(zt,t,ct,cf))∥22]\left.\mathcal{L}=\mathbb{E}_{\boldsymbol{z}_0, t, \boldsymbol{c}_t, \boldsymbol{c}_{\mathrm{r}}, \epsilon \sim \mathcal{N}(0,1)}\left[\| \epsilon-\epsilon_\theta\left(z_t, t, \boldsymbol{c}_t, \boldsymbol{c}_{\mathrm{f}}\right)\right) \|_2^2\right]L=Ez0,t,ct,cr,ϵ∼N(0,1)[∥ϵ−ϵθ(zt,t,ct,cf))∥22]
使用的就是人家Stable Diffusion原始的目标函数改了改。
先看一下原始的Stable Diffusion的目标函数:
LLDM:=EE(x),ϵ∼N(0,1),t[∥ϵ−ϵθ(zt,t)∥22]L_{L D M}:=\mathbb{E}_{\mathcal{E}(x), \epsilon \sim \mathcal{N}(0,1), t}\left[\left\|\epsilon-\epsilon_\theta\left(z_t, t\right)\right\|_2^2\right]LLDM:=EE(x),ϵ∼N(0,1),t[∥ϵ−ϵθ(zt,t)∥22]
将采样ztz_tzt使用网络ϵθ\epsilon_\thetaϵθ去噪之后和原图经过网络ϵ\epsilonϵ获得的潜变量计算L2L_2L2loss,看其重建的效果。
那再回到
L=Ez0,t,ct,cr,ϵ∼N(0,1)[∥ϵ−ϵθ(zt,t,ct,cf))∥22]\left.\mathcal{L}=\mathbb{E}_{\boldsymbol{z}_0, t, \boldsymbol{c}_t, \boldsymbol{c}_{\mathrm{r}}, \epsilon \sim \mathcal{N}(0,1)}\left[\| \epsilon-\epsilon_\theta\left(z_t, t, \boldsymbol{c}_t, \boldsymbol{c}_{\mathrm{f}}\right)\right) \|_2^2\right]L=Ez0,t,ct,cr,ϵ∼N(0,1)[∥ϵ−ϵθ(zt,t,ct,cf))∥22]
将原始图像经过ϵ\epsilonϵ之后获得潜变量,和经过网络ϵθ\epsilon_\thetaϵθ重建之后的图算L2L_2L2loss。原来Stable Diffusion中解码器要处理的是采样ztz_tzt和时间步长ttt,在这里加了两个控制条件:
- 文字prompt ctc_tct
- 任务相关的prompt cfc_fcf
训练过程中将50 %的文本提示ctc_tct随机替换为空字符串。这样有利于ControlNet网络从控制条件中识别语义内容。这样做的目的是,当Stable Diffusion没有prompt的时候,编码器能从输入的控制条件中获得更多的语义来代替prompt。(这也就是classifier-free guidance。)
效果!
这一部分作者主要是讲了如何训练不同控制条件的ControlNet的,训练方法感兴趣的自己看,这里简单展示一下作者提供好的训练出来的模型。用《青蛇劫起》里边小青做一下示范:
Canny Edge
使用Canny边缘检测生成边缘线稿,再将作为扩散模型输入。
HED
使用hed边界检测。
Depth
使用深度图生成。
Normal Maps
使用法线图生成图像。提供了Midas计算深度图并转换为法线图的扩展版本的模型。
Human Pose
使用姿势检测,获得人体骨骼的可视化姿势图像。
User Sketching
使用人类涂鸦进行生成。
Semantic Segmentation
使用语义分割。
Hough Line
使用m-lsd直线检测算法。(论文中还提到了使用传统的霍夫变换直线检测)
其他
论文中还提到了其他的,比如动漫线稿之类的,但是没有提供对应的模型,所以这里无法展示,感兴趣的可以自己去看一下论文。
写在最后
感兴趣的小伙伴,赠送全套AIGC学习资料,包含AI绘画、AI人工智能等前沿科技教程和软件工具,具体看这里。
AIGC技术的未来发展前景广阔,随着人工智能技术的不断发展,AIGC技术也将不断提高。未来,AIGC技术将在游戏和计算领域得到更广泛的应用,使游戏和计算系统具有更高效、更智能、更灵活的特性。同时,AIGC技术也将与人工智能技术紧密结合,在更多的领域得到广泛应用,对程序员来说影响至关重要。未来,AIGC技术将继续得到提高,同时也将与人工智能技术紧密结合,在更多的领域得到广泛应用。
一、AIGC所有方向的学习路线
AIGC所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面。
二、AIGC必备工具
工具都帮大家整理好了,安装就可直接上手!
三、最新AIGC学习笔记
当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。
四、AIGC视频教程合集
观看全面零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
五、实战案例
纸上得来终觉浅,要学会跟着视频一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。