ControlNet与T2IAdapter
(Double童发发——学习笔记三)ControlNet与T2IAdapter
文章目录
- (Double童发发——学习笔记三)ControlNet与T2IAdapter
- 1. ControlNet
- 结构设计
- zero convolution 为什么work?/ 为什么梯度不为零?
- 如何与原生SD结合
- 训练trick
- 2. T2IAdapter
- 结构设计
- 与SD结合
- 3. 两种方法对比与总结
- 参考
两者主要加的都是空间条件
1. ControlNet
结构设计
ControlNet将一个原始block直接复制一份成为trainable copy,其初始化权重也与之前的保持一样,然后在这个trainable copy前后设计两个zero convolution,输入的额外条件ccc与block原本的输入xxx是隔离的,一开始时ccc经过第一个zero convolution结果是0,xxx经过与0相加后进入trainable copy,得到的结果再经过第二个zero convolution,输出也为0,因此并不会改变原来网络的输出值yyy。因此,这对原生的SD没有任何改变,如果我们使用不同的初始化可能会导致给SD导致负影响,我们从0开始,保证了优化从0之后就往给SD正影响的方向移动,初始化为0的作用是使训练难度降低。
在第一个zero convolution处,输入的额外条件ccc与block原本的输入xxx是隔离的,这是因为xxx是加噪的,在不同的时间步上,加的噪声也是不一样的。如果我们不通过第一个zero convolution的处理,而让输入的额外条件ccc与block原本的输入xxx直接接触,ccc的图像特征就会受到xxx中噪声的影响,这不利于稳定训练。
利用2D特征作为例子,给定一个输入的特征图x∈Rh×w×cx\in\mathbb{R}^{h\times w\times c}x∈Rh×w×c,一个神经网络block F(⋅;Θ)\mathcal{F}(\cdot;\Theta)F(⋅;Θ)的输出写为:
y=F(x;Θ)y=\mathcal{F}(x;\Theta)y=F(x;Θ)
我们用Z(⋅;⋅)\mathcal{Z}(\cdot;\cdot)Z(⋅;⋅)代表zero convolution的操作,用{Θz1,Θz2}\{\Theta_{\mathrm{z1}},\Theta_{\mathrm{z2}}\}{Θz1,Θz2}分别代表两个zero convolution层的参数,则ControlNet的结构过程可以写为:
yc=F(x;Θ)+Z(F(x+Z(c;Θz1);Θc);Θz)y_{\mathfrak{c}}=\mathcal{F}(x;\Theta)+\mathcal{Z}(\mathcal{F}(x+\mathcal{Z}(c;\Theta_{\mathrm{z1}});\Theta_{\mathrm{c}});\Theta_{\mathrm{z}})yc=F(x;Θ)+Z(F(x+Z(c;Θz1);Θc);Θz)
在训练的第一次前向传播时,各个模块的输出如下:
{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\begin{cases}\mathcal{Z}(c;\Theta_\mathrm{z1})=\mathbf{0}\\\mathcal{F}(x+\mathcal{Z}(c;\Theta_\mathrm{z1});\Theta_\mathrm{c})=\mathcal{F}(x;\Theta_\mathrm{c})=\mathcal{F}(x;\Theta)\\\mathcal{Z}(\mathcal{F}(x+\mathcal{Z}(c;\Theta_\mathrm{z1});\Theta_\mathrm{c});\Theta_\mathrm{z2})=\mathcal{Z}(\mathcal{F}(x;\Theta_\mathrm{c});\Theta_\mathrm{z2})=\mathbf{0}&\end{cases}⎩⎨⎧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
因为zero convolution层的作用,并不影响原本SD的流程,在反向传播时,才会逐步将zero convolution层优化为正常的卷积层。
zero convolution是1x1\mathrm{1x1}1x1的卷积层,因此其并不聚合空间的信息,只是聚合不同通道的信息,这么做可以减少卷积层对条件图像 ccc 的影响。
zero convolution 为什么work?/ 为什么梯度不为零?
我们假设卷积层的权重为零,则梯度为零。然而这是不正确的
假设是零卷积层的处理过程为:
y=wx+by=wx+by=wx+b
则每一项的梯度为:
∂y∂w=x∂y∂x=w∂y∂b=1\frac{\partial y}{\partial w}=x\quad\frac{\partial y}{\partial x}=w\quad\frac{\partial y}{\partial b}=1∂w∂y=x∂x∂y=w∂b∂y=1
如果 w=0w = 0w=0 且 x≠0x \neq 0x=0,则:
∂y∂w=x≠0∂y∂x=w=0∂y∂b=1≠0\frac{\partial y}{\partial w}=x\neq0\quad\frac{\partial y}{\partial x}=w=0\quad\frac{\partial y}{\partial b}=1\neq0∂w∂y=x=0∂x∂y=w=0∂b∂y=1=0
回想一下梯度下降和链式法则:
w←w−α∂y∂w,w←w−α∂y∂⋅…∂y∂w⏟≠0w\leftarrow w-\alpha\frac{\partial\mathcal{y}}{\partial w},\\\ w\leftarrow w-\alpha\frac{\partial\mathcal{y}}{\partial\cdot}\ldots\frac{\partial\mathcal{y}}{\underbrace{\partial w}_{\neq0}}w←w−α∂w∂y, w←w−α∂⋅∂y…=0∂w∂y
这意味着只要x≠0x\neq0x=0,一次的梯度下降迭代之后就会使w≠0w \neq 0w=0。一开始,当权重值 w=0w = 0w=0 时,输入特征 xxx 通常不为0。结果,虽然 xxx 上的梯度由于零卷积而变为0,但权重和偏置的梯度不受影响。尽管如此,在一个梯度下降步骤之后,权重值 www 将更新为非零值(因为 yyy 对 www 的偏导数非零)。
如何与原生SD结合
ControlNet主要是复制了SD中的编码层和Middle Block,共13个层。zero convolution层的结果则是加到Middle Block和解码层上。
ControlNet用了条件预处理网络,由一个4层的基础卷积层构成,每个卷积的卷积核为4x4\mathrm{4x4}4x4 步长为2x2\mathrm{2x2}2x2,激活函数为ReLU,通道数分变为16、32、64、128,目的是为了使得条件图像ccc也转换到与隐变量zzz相同的维度大小(128x64x64\mathrm{128x64x64}128x64x64),才能进行相加操作。
训练trick
训练过程50%的概率将文本prompt变为空字符串,增强模型对条件图像本身的语义理解能力。
上图是ControlNet中的突然学会现象,在6100步时还不能学会如何控制,但是在6133步时就突然学会。这是zero convolution在前6133步不帮正忙也不帮倒忙,降低了训练的难度。
2. T2IAdapter
T2I-Adapter,一个简单而小的模型,为预训练的文本-到-图像(T2I)模型提供了额外的指导,同时不影响其原始网络拓扑和生成能力。得益于T2I-adapter,原始T2I模型(例如Stable Diffusion)难以准确生成的, T2I-Adapter可以得到更具想象力的结果。可以使用各种指导,如颜色、深度、草图、语义分割和关键点。可以使用T2I-Adapter进一步实现本地编辑和可组合指导。
结构设计
T2IAdapter自己提出了一个模型,将条件输入,是一种插件模型。
T2IAdapter的实现细节。首先,是Pixel Unshuffle(Pixel shuffle的逆操作)将输入的condition,如边缘检测图 512x512x1\mathrm{512x512x1}512x512x1 变为 64x64x64\mathrm{64x64x64}64x64x64 ,用以替代VAE编码器的效果,将条件condition编码到latent space。因为T2IAdapter的条件特征是加在编码器上的,所以这里后续有4个block与UNet的编码层对应。
与SD结合
T2IAdapter与原生SD的融合,是将block对应的输出直接与SD中编码的特征相加:
Fc={Fc1,Fc2,Fc3,Fc4}Fenc={Fenc1,Fenc2,Fenc3,Fenc4}Fc=FAD(C)F^enci=Fenci+Fci,i∈{1,2,3,4}\begin{aligned}&\mathbf{F}_{c}=\{\mathbf{F}_{c}^{1},\mathbf{F}_{c}^{2},\mathbf{F}_{c}^{3},\mathbf{F}_{c}^{4}\}\\&\mathbf{F}_{enc}=\{\mathbf{F}_{enc}^{1},\mathbf{F}_{enc}^{2},\mathbf{F}_{enc}^{3},\mathbf{F}_{enc}^{4}\}\\&\mathbf{F}_c=\mathcal{F}_{AD}(\mathbf{C})\\&\hat{\mathbf{F}}_{enc}^{i}=\mathbf{F}_{enc}^{i}+\mathbf{F}_{c}^{i},i\in\{1,2,3,4\}\end{aligned}Fc={Fc1,Fc2,Fc3,Fc4}Fenc={Fenc1,Fenc2,Fenc3,Fenc4}Fc=FAD(C)F^enci=Fenci+Fci,i∈{1,2,3,4}
3. 两种方法对比与总结
ControlNet与T2I Adapter所要实现的目标一致,除了语言提示语,增加二维空间图像对生成结果的控制,克服了语言描述难以精细控制图像生成的问题,显著提升生成结果控制的精细程度。两种方法均能同时控制多种元素的生成,并获得不错的生成效果,且均不需要对原始扩散大模型进行训练,都是添加新的"插件模型”达到目标,训练成本相对较低。
ControlNet和T2I Adapter属于同一时期的成果,两个论文互相引用,但都没有对两种方法进行比较,个人认为在实战中ControlNet使用频率更高,效果更稳定;T2I Adapter控制元素更多,更加灵活。
参考
【AI知识分享】结合代码深度分析ControlNet与T2IAdapter到底是如何对Stable Diffusion添加条件控制的_哔哩哔哩_bilibili
Stable Diffusion — ControlNet 超详细讲解_stable diffusion controlnet-CSDN博客