前排提示照片已经获得小姐姐许可。
光知道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的扩散模型,其中原始的神经网络输入获得,参数用表示。
也就是下图这个样子。
ControlNet中,就是将模型原始的神经网络锁定,设为locked copy。
然后将原始网络的模型复制一份,称之为trainable copy,在其上进行操作施加控制条件。然后将施加控制条件之后的结果和原来模型的结果相加获得最终的输出。
经过这么一顿操作之后,施加控制条件之后,最后将原始网络的输出修改为:
其中zero convolution,也就是零卷积层是初始化weight和bias为0,两层零卷积的参数为。
将控制条件通过零卷积之后,与原始输入相加,相加之后进入ControlNet的复制神经网络块中,将网络输出再做一次零卷积之后与原始网络的输出相加。
初始化之后未经训练的ControlNet参数应该是这样的:
也就是说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的条件空间上,训练过程中添加了一个小网络将图像空间条件转化为特征图条件。
这个网络是四层卷积神经网络,卷积核为4×4,步长为2,通道16,32,64,128,初始化为高斯权重。这个网络训练过程是和整个ControlNet进行联合训练。
或者我们可以把他的图改吧改吧,画成这样:
训练过程
训练的目标函数为:
使用的就是人家Stable Diffusion原始的目标函数改了改。
先看一下原始的Stable Diffusion的目标函数:
将采样使用网络去噪之后和原图经过网络获得的潜变量计算loss,看其重建的效果。
那再回到
将原始图像经过之后获得潜变量,和经过网络重建之后的图算loss。原来Stable Diffusion中解码器要处理的是采样和时间步长,在这里加了两个控制条件:
- 文字prompt
- 任务相关的prompt
训练过程中将50 %的文本提示随机替换为空字符串。这样有利于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直线检测算法。(论文中还提到了使用传统的霍夫变换直线检测)
其他
论文中还提到了其他的,比如动漫线稿之类的,但是没有提供对应的模型,所以这里无法展示,感兴趣的可以自己去看一下论文。
本文正在参加「金石计划」