ControlNet原理解析

前排提示照片已经获得小姐姐许可。

image.png

光知道ControlNet好用,不想知道它背后的原理么?今天就看一看这篇论文,带大家了解一下ControlNet是如何炼成的。

image.png


ControlNet是干嘛的

我们知道现在文本到图像生成很火爆,你只需要输入文字就可以获得对应的输出,这个任务的发展多亏了扩散模型的发展。

而我们今天要说的ControlNet的作用就是能够控制扩散模型,生成更接近用户需求的图。

我们用几个图示范一下:

假如我们只用文字去生成图像,我们给模型输入文本prompt:

a girl, long hair, blond hair, black eyes, black coat, winter, snow

那模型会出来这些图:

image.png

我们可以看到,我们输入的要素都符合了。但是差别又很大,大在哪里?每个妹子动作差异都好大。

那现在我们就可以掏出ControlNet了,用ControlNet来控制你生成的人物的动作。

比如下图这样,可以看到即使我换了画风(换了模型的checkpoint)生成的人物动作也是一样的, 并且满足我前边输入的条件。

image.png

那我做了什么才让模型能稳定输出相同的人物动作呢?下面请出我们的仙女姐姐尚尚:

为我们生成的妹子提供动作的是我们的尚影嫣小姐姐,我把她的照片放到ControlNet中作为控制条件,这里使用的是ControlNet的Depth功能,ControlNet会根据小姐姐提取一个深度图,然后按照人物深度图轮廓去生成我们的人物。

下图你看到的就是文本prompt控制ControlNet图像条件控制相互作用的结果。

既符合文本prompt:a girl, long hair, blond hair, black eyes, black coat, winter, snow,又保持了小姐姐的大致动作形态。

image.png

当然,如果我们把文字控制删除一点,只留下a girl, long hair, black eyes,我们可以得到更接近小姐姐原图的结果。

image.png

好了,美女看完了,那我们就介绍一下这个论文吧。

ControlNet 网络设计

在一个扩散模型中,如果不加ControlNet的扩散模型,其中原始的神经网络F\mathcal FF输入xxx获得yyy,参数用Θ\ThetaΘ表示。

y=F(x;Θ)y = \mathcal F(x;\Theta)y=F(x;Θ)

也就是下图这个样子。

image.png

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​}。

image.png

将控制条件通过零卷积之后,与原始输入相加,相加之后进入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。

image.png

在这之前需要注意:

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进行联合训练。

或者我们可以把他的图改吧改吧,画成这样:

image.png

训练过程

训练的目标函数为:

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_2L2​loss,看其重建的效果。

那再回到

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_2L2​loss。原来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边缘检测生成边缘线稿,再将作为扩散模型输入。

image.png

HED

使用hed边界检测。

image.png

Depth

使用深度图生成。

image.png

Normal Maps

使用法线图生成图像。提供了Midas计算深度图并转换为法线图的扩展版本的模型。

image.png

Human Pose

使用姿势检测,获得人体骨骼的可视化姿势图像。

image.png

User Sketching

使用人类涂鸦进行生成。

image.png

image.png

Semantic Segmentation

使用语义分割。

image.png

image.png

Hough Line

使用m-lsd直线检测算法。(论文中还提到了使用传统的霍夫变换直线检测)

image.png

其他

论文中还提到了其他的,比如动漫线稿之类的,但是没有提供对应的模型,所以这里无法展示,感兴趣的可以自己去看一下论文。


写在最后

感兴趣的小伙伴,赠送全套AIGC学习资料,包含AI绘画、AI人工智能等前沿科技教程和软件工具,具体看这里。

AIGC技术的未来发展前景广阔,随着人工智能技术的不断发展,AIGC技术也将不断提高。未来,AIGC技术将在游戏和计算领域得到更广泛的应用,使游戏和计算系统具有更高效、更智能、更灵活的特性。同时,AIGC技术也将与人工智能技术紧密结合,在更多的领域得到广泛应用,对程序员来说影响至关重要。未来,AIGC技术将继续得到提高,同时也将与人工智能技术紧密结合,在更多的领域得到广泛应用。

在这里插入图片描述

一、AIGC所有方向的学习路线

AIGC所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面。

在这里插入图片描述

在这里插入图片描述

二、AIGC必备工具

工具都帮大家整理好了,安装就可直接上手!
在这里插入图片描述

三、最新AIGC学习笔记

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。
在这里插入图片描述
在这里插入图片描述

四、AIGC视频教程合集

观看全面零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

在这里插入图片描述

五、实战案例

纸上得来终觉浅,要学会跟着视频一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/12636.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

内存函数:memcpy(拷贝),memmove(拷贝),memcmp(比较),memset(设置)

内存函数 一.memcpy(内存拷贝1)1.函数使用2.模拟实现 二.memmove(内存拷贝2)1.函数使用2.模拟实现 三.memcmp(内存比较)1.函数使用2.模拟实现 四.memset(内存设置)1.函数使用2.模拟实…

【Linux】用户组、用户、文件权限(ugo权限),权限掩码,chmod,chown,suid,sgid,sticky,su,sudo

用户组 注意:普通用户只能查看有哪些组,不能创建/修改/删除,会提示:用户名 is not in the sudoers file.This incident will be reported. groupadd 用户组名新建用户组cat /etc/group查看有哪些组(普通用户可以操作…

Windows下配置TortoiseGit 访问Ubuntu虚拟机下Samba共享目录

前言: 本文记录学习使用 Git 版本管理工具的学习笔记,通过阅读参考链接中的博文和实际操作,快速的上手使用 Git 工具。 本文参考了引用链接博文里的内容。 引用: 【TortoiseGit】TortoiseGit安装和配置详细说明-CSDN博客 Git版本管理可视…

Java——对象的打印

当我们运行如下代码: public class Person {String name;String gender;int age;public Person(String name,String gender,int age){this.name name;this.gender gender;this.age age;}public static void main(String[] args){Person person new Person(&quo…

Matlab读取数据文件

MATLAB可以读取很多类型的数据文件,包括文本文件、Excel文件、MAT文件等。以下是一些常见的数据读取函数: 文本文件: load 函数:用于读取MATLAB的二进制文件(.mat文件)。fscanf 函数:用于读取AS…

QT客户端开发的注意事项

QT客户端开发是一个涉及图形用户界面(GUI)设计、网络编程、数据库交互等多个方面的复杂过程。以下是在进行QT客户端开发时应注意的一些关键事项,通过关注这些事项,可以提高QT客户端应用的质量和开发效率。北京木奇移动技术有限公司…

Eclipse下载安装教程(包含JDK安装)【保姆级教学】【2024.4已更新】

目录 文章最后附下载链接 第一步:下载Eclipse,并安装 第二步:下载JDK,并安装 第三步:Java运行环境配置 安装Eclipse必须同时安装JDK !!! 文章最后附下载链接 第一步&#xf…

微软推出的Microsoft Fabric 到底是什么?

近期,总有客户问小编,微软推出的 Microsoft Fabric 是什么?这个产品有什么特别之处呢?希望下面这篇文章能为大家解开一些疑惑。 微软Fabric是2023年5月推出的一个数据分析平台,它将关键数据管理和分析工作负载整合到一…

go语言控制goroutine协程退出的2种方法总结

我们知道,在go语言中,goroutine的执行会随着main线程的退出而终结, 即如果main线程退出,则所有的goroutine都会被强制退出,不管你是否已经执行完毕。 如果我们希望main进程等待所有的goroutine执行完毕后再退出&#…

【设计模式】JAVA Design Patterns——Acyclic Visitor(非循环访问者模式)

🔍目的 允许将新功能添加到现有的类层次结构中,而不会影响这些层次结构,也不会有四人帮访客模式中那样循环依赖的问题。 🔍解释 真实世界例子 我们有一个调制解调器类的层次结构。 需要使用基于过滤条件的外部算法(是…

奖金+1 万,OpenTenBase 开源核心贡献挑战赛,KB 专家助力其跑在 K8s 上

OpenTenBase 是由开放原子开源基金会孵化及运营的开源项目,是一款开放中立的企业级分布式 HTAP 开源数据库。OpenTenBase 具备高扩展性、商业数据库语法兼容、分布式 HTAP 引擎、多级容灾和多维度资源隔离等能力,已成功应用于金融、医疗、航天等行业的核…

FlyFlow:支持驳回后自动跨节点跳回

本周更新 新增:审批节点驳回(拒绝配置的驳回)支持自动跳回当前节点新增:修改数据节点新增:删除数据节点新增:子流程支持配置自动跳过发起人节点优化:两个项目合并一个单体项目优化:…

Hadoop阶段性技能抽检题,无直接答案但有提示信息

项目名:Hadoop平台及组件的部署管理 考核内容: 考核以大数据技术为核心内容,重点考查同学们基于Hadoop平台环境下,利用Hadoop技术生态组件,综合软件开发相关技术,解决实际问题的能力,所有学生在…

LeetCode hot100-38-Y

226. 翻转二叉树给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。这道题莫名其妙做出来了,看评论好多人都是莫名其妙做出来的。就是连续做了几道题有感觉了。很难解释。 我的做法 后序递归 class Solution {public TreeNode i…

LeetCode:2589.完成所有任务的最少时间(贪心 Java)

目录 完成所有任务的最少时间 题目描述: 实现代码与解析: 贪心 原理思路: 完成所有任务的最少时间 题目描述: 你有一台电脑,它可以 同时 运行无数个任务。给你一个二维整数数组 tasks ,其中 tasks[i] …

Linux 系统下进程异常的处理方式

Linux 系统异常进程处理 一、僵尸进程 说明:僵尸进程对系统来说就是系统已经接管不了并处于异常状态的进程,既不会自动释放,也不能被系统接管,下面列出几种查看并kill僵尸进程的方式 。 方式一、使用如下命令查看目前系统状态为…

【C语言】水仙花数

问题 水仙花数(Narcissistic number)也被称为超完全数字不变数(pluperfect digital invariant, PPDI)、自恋数、自幂数或阿姆斯壮数数(Armstrong number)。 它是指一个n位数(n≥3)…

【C++】---继承

【C】---继承 一、继承的概念及定义1、继承的概念2、定义语法格式3、继承基类成员访问方式的变化 二、基类 和 派生类 的对象之间的赋值转换1、赋值规则2、切片(1)子类对象 赋值 给 父类对象(2)子类对象 赋值 给 父类指针&#xf…

Promise链式调用与错误处理

Promise链式调用是一种处理异步操作的方法,它可以依次执行多个异步任务,并且可以在每个任务完成后进行后续操作。 在Promise链式调用中,每个任务都返回一个Promise对象,可以通过调用.then()方法来指定任务完成后的操作&#xff0…