【stable diffusion原理解读通俗易懂,史诗级万字爆肝长文,喂到你嘴里】

news2024/11/26 0:41:40

img

文章目录

    • 一、前言(可跳过)
    • 二、stable diffusion
      • 1.clip
      • 2.diffusion model
        • forward diffusion (前向扩散)
        • 逆向扩散(reverse diffusion)
        • 采样图
        • 阶段小结
      • 3.Unet model
        • timestep_embedding采用正余弦编码
    • 三、stable diffusion webui扩展

个人网站

一、前言(可跳过)

hello,大家好我是 Tian-Feng,今天介绍一些stable diffusion的原理,内容通俗易懂,因为我平时也玩Ai绘画嘛,所以就像写一篇文章说明它的原理,这篇文章写了真滴挺久的,如果对你有用的话,希望点个赞,谢谢。

stable diffusion作为Stability-AI开源图像生成模型,其出现也是不逊于ChatGPT,其发展势头丝毫不差于midjourney,加上其众多插件的加持,其上线也是无线拔高,当然,手法上也稍微比midjourney复杂点。论文 源码

至于为什么开源,**创始人:我这么做的原因是,我认为这是共同叙事(shared narrative)的一部分,有人需要公开展示发生了什么。再次强调,这应该默认就是开源的。因为价值不存在于任何专有模型或数据中,我们将构建可审计(auditable)的开源模型,即使其中包含有许可数据。**话不多说,开整。

二、stable diffusion

对于上面原论文的图片可能小伙伴理解有困难,但是不打紧,我会把上面图片分成一个个单独的模块进行解读,最后组合在一起,相信你们一定可以理解图片每一步干了什么事。

首先,我会画一个简化模型图对标原图,以方便理解。让我们从训练阶段开始,可能你们发现少了VAEdecoder,这是因为我们训练过程是在潜空间完成,decoder我们放在第二阶段采样阶段说,我们所使用的stablediffusion webui画图通常是在采样阶段,至于训练阶段,目前我们大多数普通人是根本完成不了的,它所需要训练时间应该可以用GPUyear来计量,(单V100的GPU要一年时间),如果你有100张卡,应该可以一个月完成。至于ChatGPT光电费上千万美金,上万GPU集群,感觉现在AI拼的就是算力。又扯远了,come back
img

1.clip

我们先从提示词开始吧,我们输入一段提示词a black and white striped cat(一条黑白条纹的猫),clip会把文本对应一个词表,每个单词标点符号都有相对应的一个数字,我们把每个单词叫做一个token,之前stablediffusion输入有限制只能75个单词(现在没了),也就是75个token,看上面你可能发现6个单词怎么对应8个token,这是因为还包含了起始token和结束token,每个数字又对应这一个768维的向量,你可以看作每个单词的身份证,而且意思非常相近的单词对应的768维向量也基本一致。经过clip我们得到了一个(8,768)的对应图像的文本向量。

stable diffusion所使用的是openAi的clip的预训练模型,就是别人训练好的拿来用就行,那clip是怎么训练出来的呢?他是怎么把图片和文字信息对应呢?(下面扩展可看可跳过,不影响理解,只需要知道它是用来把提示词转成对应生成图像的文本向量即可)

CLIP需要的数据为图像及其标题,数据集中大约包含4亿张图像及描述。应该是直接爬虫得来,图像信息直接作为标签,训练过程如下:

CLIP 是图像编码器和文本编码器的组合,使用两个编码器对数据分别进行编码。然后使用余弦距离比较结果嵌入,刚开始训练时,即使文本描述与图像是相匹配的,它们之间的相似性肯定也是很低的。

img

随着模型的不断更新,在后续阶段,编码器对图像和文本编码得到的嵌入会逐渐相似。在整个数据集中重复该过程,并使用大batch size的编码器,最终能够生成一个嵌入向量,其中狗的图像和句子「一条狗的图片」之间是相似的。

给一些提示文本,然后每种提示算相似度,找到概率最高的即可img

2.diffusion model

上面我们已经得到了unet的一个输入了,我们现在还需要一个噪声图像的输入,假如我们输入的是一张3x512x512的猫咪图像,我们不是直接对猫咪图像进行处理,而是经过VAE encoder把512x512图像从pixel space(像素空间)压缩至latent space(潜空间)4x64x64进行处理,数据量小了接近64倍。

[img

潜在空间简单的说是对压缩数据的表示。所谓压缩指的是用比原始表示更小的数位来编码信息的过程。维度降低会丢失一部分信息,然而在某些情况下,降维不是件坏事。通过降维我们可以过滤掉一些不太重要的信息你,只保留最重要的信息。

得到潜空间向量后,现在来到扩散模型,为什么图像加噪后能够还原,秘密都在公式里,这里我以DDPM论文作为理论讲解,论文,当然还有改进版本DDIM等等,感兴趣自己看

forward diffusion (前向扩散)

  • 首先是forward diffusion (前向扩散),也就是加噪过程,最后就快变成了个纯噪声

  • 每一个时刻都要添加高斯噪声,后一时刻都是由前一刻是增加噪声得到

img

那么是否我们每一次加噪声都要从前一步得到呢,我们能不能想要第几步加噪图像就能得到呢?答案是YES,作用是:我们训练过程中对图像加噪是随机的,假如 我们随机到100步噪声,(假设设置时间步数200步),如果要从第一步加噪,得到第二步,循环往复,太费时间了,其实这些加的噪声有规律的,我们现在的目标就是只要有原始图像X0,就可以得到任意时刻图像加噪声的图像,而不必一步一步得到想要的噪声图像。

在这里插入图片描述

我来对上述作讲解,其实该标住的我都标的很清楚了,

第一,αt范围0.9999-0.998,

第二,图像加噪是符合高斯分布的,也就是在潜空间向量加的噪声是符合均值为0,方差为1的,将Xt-1带入Xt中,为什么两项可以合并,因为Z1Z2都是符合高斯分布,那么他们相加Z2’也符合,并且它们的方差和为新的方差,所有把他们各自的方差求和,(那个带根号的是标准差),如果你无法理解,可以把它当做一个定理。在多说一句,对Z–>a+bZ,那么Z的高斯分别也从(0,σ)–>(a,bσ),现在我们得到了Xt跟Xt-2的关系

第三,如果你再把Xt-2带入,得到与Xt-3的关系,并且找到规律,就是α的累乘,最后得到Xt与X0的关系式,现在我们可以根据这个式子直接得到任意时刻的噪声图像。

第四,因为图像初始化噪声是随机的,假设你设置的时间步数(timesteps)为200,就是把0.9999-0.998区间等分为200份,代表每个时刻的α值,根据Xt和X0的公式,因为α累乘(越小),可以看出越往后,噪声加的越快,大概1-0.13的区间,0时刻为1,这时Xt代表图像本身,200时刻代表图像大概α为0.13噪音占据了0.87,因为是累乘所以噪声越加越大,并不是一个平均的过程。

第五,补充一句,重参数化技巧(Reparameterization Trick)
如果X(u,σ2),那么X可以写成X=μ十σZ的形式,其中Z~Ν(0,1)。这就是重参数化技巧。

重参数化技巧,就是从一个分布中进行采样,而该分布是带有参数的,如果直接进行采样(采样动作是离散的,其不可微),是没有梯度信息的,那么在BP反向传播的时候就不会对参数梯度进行更新。重参数化技巧可以保证我们从进行采样,同时又能保留梯度信息。

逆向扩散(reverse diffusion)

  • 前向扩散完毕,接下来是逆向扩散(reverse diffusion),这个可能比上面那个难点,如何根据一个噪声图像一步步得到原图呢,这才是关键,

img

  • 逆向开始,我们目标是Xt噪声图像得到无噪声的X0,先从Xt求Xt-1开始,这里我们先假设X0是已知(先忽略为什么假设已知),后面会替换它,至于怎么替换,前向扩散不是已知Xt和X0的关系吗,现在我们已知的是Xt,反过来用Xt来表示X0,但是还有一个Z噪声是未知的,这个时候就要Unet上场了,它需要把噪声预测出来。
  • 这里借助贝叶斯公式(就是条件概率),我们借助贝叶斯公式结果,以前写过一个文档

img

就是已知Xt求Xt-1,反向我们不知道怎么求,但是求正向,如果我们已知X0那么这几项我们都可以求出来。
在这里插入图片描述
(https://tianfeng.space/wp-content/uploads/2023/05/下载-3.png)(https://tianfeng.space/wp-content/uploads/2023/05/下载-3.png)
开始解读,既然这三项都符合高斯分别,那带入高斯分布(也可以叫正态分布),它们相乘为什么等于相加呢,因为e2 * e3 =e2+3,这个能理解吧(属于exp,就是e次方),好,现在我们得到了一个整体式子,接下来继续化简

首先我们把平方展开,未知数现在只有Xt-1,配成AX2+BX+C格式,不要忘了,即使相加也是符合高斯分布,现在我们把原高斯分别公式配成一样的格式,红色就是方差的倒数,把蓝色乘方差除2就得到了均值μ(下面显示是化简的结果,如果你有兴趣自己,自己化简),回归X0,之前说X0假设已知,现在转成Xt(已知)表示,代入μ,现在未知数只剩下Zt,在这里插入图片描述

  • Zt其实就是我们要估计的每个时刻的噪声
    - 这里我们使用Unet模型预测
    - 模型的输入参数有三个,分别是当前时刻的分布Xt和时刻t,还有之前的文本向量,然后输出预测的噪声,这就是整个过程了,

img

  • 上面的Algorithm 1是训练过程,

其中第二步表示取数据,一般来说都是一类猫,狗什么的,或者一类风格的图片,不能乱七八糟什么图片都来,那模型学不了。

第三步是说每个图片随机赋予一个时刻的噪声(上面说过),

第四步,噪声符合高斯分布,

第五步,真实的噪声和预测的噪声算损失(DDPM输入没有文本向量,所有没有写,你就理解为多加了一个输入),更新参数。直到训练的输出的噪声和真实噪声相差很小,Unet模型训练完毕

  • 下面我们来到Algorithm2采样过程
  1. 不就是说Xt符合高斯分布嘛
  2. 执行T次,依次求Xt-1到X0,不是T个时刻嘛
  3. Xt-1不就是我们逆向扩散推出的公式,Xt-1=μ+σZ,均值和方差都是已知的,唯一的未知噪声Z被Unet模型预测出来,εθ这个是指已经训练好的Unet,

采样图

  • 为了方便理解,我分别画出文生图和图生图,如果使用stable diffusion webui画图的人一定觉得很熟悉,如果是文生图就是直接初始化一个噪声,进行采样,
  • 图生图则是在你原有的基础上加噪声,噪声权重自己控制,webui界面是不是有个重绘幅度,就是这个,
  • 迭代次数就是我们webui界面的采样步数,
  • 随机种子seed就是我们初始随机得到的一个噪声图,所以如果想要复刻得到一样的图,seed要保持一致

img

img

阶段小结

我们现在再来看这张图,除了Unet我没讲(下面会单独介绍),是不是简单多了,最左边不就是像素空间的编码器解码器,最右边就是clip把文本变成文本向量,中间上面的就是加噪,下面就是Unet预测噪声,然后不停的采样解码得到输出图像。这是原论文采样图,没画训练过程。

img

3.Unet model

unet模型相信小伙伴们都或多或少知道,就是多尺度特征融合,像FPN图像金字塔,PAN,很多都是差不多的思想,一般使用resnet作为backbone(下采样),充当编码器,这样我们就得到多个尺度的特征图,然后在上采样过程中,上采样拼接(之前下采样得到的特征图),这是一个普通的Unet

img

那stablediffusion的Unet有什么不一样呢,这里找到一张图,佩服这位小姐姐有耐心,借一下她的图

img

我解释一下和ResBlock模块和SpatialTransformer模块,输入为timestep_embedding,context 以及input,三个输入分别是时间步数,文本向量,加噪图像,时间步数你可以理解为transformer里的位置编码,在自然语言处理中用来告诉模型一句话每个字的位置信息,不同的位置可能意思大不相同,而在这,加入时间步数信息,可以理解为告诉模型加入第几步噪声的时刻信息(当然这是我的理解)。

timestep_embedding采用正余弦编码

img

ResBlock模块输入为时间编码和卷积后图像输出,把它们相加,这就是它的作用,具体细节不说了,就是卷积,全连接,这些很简单。

SpatialTransformer模块输入为文本向量和上一步ResBlock的输出,

img

里面主要讲一下cross attention,其他都是一些维度的变换,卷积操作和各种归一化Group Norm,Layer norm,

利用cross attention将latent space(潜空间)的特征与另一模态序列(文本向量)的特征融合,并添加到diffusion model的逆向过程,通过Unet逆向预测每一步需要减少的噪音,通过GT噪音与预测噪音的损失函数计算梯度。

看右下角图,可以知道Q为latent space(潜空间)的特征,KV则都是文本向量连两个全连接得到,剩下就是正常的transformer操作了,QK相乘后,softmax得到一个分值,然后乘V,变换维度输出,你可以把transformer当做一个特征提取器,它可以把重要信息给我们显现出来(仅帮助理解),差不多就是这样了,之后操作都差不多,最后输出预测的噪声。

这里你肯定得熟悉transformer,知道什么是self attention,什么是cross attention不懂找篇文章看看,感觉不是可以简单解释清楚的。

完毕,拜拜,显示一些webui对比图

三、stable diffusion webui扩展

参数clip

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

华为OD机试真题 Java 实现【求符合要求的结对方式】【2023Q1 100分】,附详细解题思路

一、题目描述 用一个数组A代表程序员的工作能力,公司想通过结对编程的方式提高员工的能力,假设结对后的能力为两个员工的能力之和,求一共有多少种结对方式使结对后能力为N。 二、输入描述 6 2 3 3 4 5 1 6 第一行为员工的总人数&#xff…

精简总结:一文说明软件测试基础概念

基础概念-1 基础概念-2 目录 一、什么是软件测试? 二、软件测试的特点 三、软件测试和开发的区别 1、内容: 2、技能区别 3、工作环境 4、薪水 5、发展前景 6、繁忙程度 7、技能要求 四、软件测试与调试的区别 1、角色 2、目的 3、执行的阶…

Lecture 7 Deep Learning for NLP: Feedforward Networks

目录 Deep LearningFeedforward Neural Network 前馈神经网络Neuron 神经元Output Layer 输出层OptimizationRegularization 正则化Topic Classification 主题分类Language Model as Classifiers 语言模型作为分类器Word Embeddings 词嵌入Training a Feed-Forward Neural Netw…

RVOS操作系统协作式多任务切换实现-03

RVOS操作系统协作式多任务切换实现-03 任务(task)多任务 (Multitask)任务上下文(Context)多任务系统的分类协作式多任务 创建和初始化第 1 号任务切换到第一号任务执行协作式多任务 - 调度初始化和任务创建…

虚拟机-安装与使用2023

虚拟机-安装与使用 前言 一、虚拟机 1.VMware 2.Virtualbox 二、VMware 的下载 三、VMware 的安装 四、验证是否安装成功 五、运行 VMware 六、VMware 上安装其它操作系统 安装 Windows 10安装 CentOS-Linux安装 Kali-Linux 七、VMware 常用功能同步时间系统备份克隆快照内存设…

黑马Redis视频教程高级篇(多级缓存案例导入说明)

目录 一、安装MYSQL 1.1、准备目录 1.2、运行命令 1.3、修改配置 1.4、重启 二、导入SQL 三、导入Demo工程 3.1、分页查询商品 3.2、新增商品 3.3、修改商品 3.4、修改库存 3.5、删除商品 3.6、根据id查询商品 3.7、根据id查询库存 3.8、启动 四、导入商品查询…

Maven高级——私服(完结撒花!)

作用与介绍 一个公司内有两个项目组,如果其中一个开发了一个依赖tlias-utils,另一个项目组要使用的话要么就是传过来直接install放到自己的本地仓库里面的。 但是也可以搭建一个公共仓库,专门供公司局域网内部使用,也就是所谓私服。 然后在…

chatgpt赋能python:Python反向函数:在编程中的威力

Python反向函数:在编程中的威力 在Python中,反向函数是一个强大且常用的工具,可以帮助程序员在编写代码时更加高效和精确地处理数据。在本文中,我们将讨论Python反向函数的用途和实现,并详细介绍如何在您的代码中使用…

Java007——Java注释介绍

围绕以下3点介绍: 1、什么是Java注释? 2、Java注释的作用? 3、Java注释长什么样,以及怎么使用Java注释? 一、什么是Java注释? Java注释是在Java程序中用来描述代码的特殊语句。 注释被忽略并且不被编译器…

MySQL表的增删改查

目录 一、Create 1.insert 2.更新 3.替换 二、Retrieve(查找) 1.select 2.where 3. 结果排序 4. 筛选分页结果 三、Update 四、Delete 1.删除数据 2.截断表 五、聚合函数 1.count: 2.avg 3.sum 4.max 5.min 六、Group …

微信小程序开发实战 ②④(自定义 TabBar练习)

作者 : SYFStrive 博客首页 : HomePage 📜: 微信小程序 📌:个人社区(欢迎大佬们加入) 👉:社区链接🔗 📌:觉得文章不错可以点点关注 &#x1f4…

十四、神经风格迁移

文章目录 1、神经风格迁移2、生成图片的代价函数THE END 1、神经风格迁移 \qquad 神经风格迁移就是将一幅原有的图片(content picture, C),对照着一幅风格图片(style picture, S),生成一幅新的图片(generated picture, G),如下图所示&#xf…

k8s istio 集成 多版本应用服务 和 网格监测

说明 博客文章地址:https://blog.taoluyuan.com/posts/istio-getting-started/ 本主要是内容: 使用 istioctl 安装 istio采用 istio 官方提供 的 应用bookinfo,实现多版本的服务应用部署istio 网关 gateway,vs,dr 的基本使用利用监测工具 prometheus,grafana,jaeger 查看 ist…

关于EMC Unity 存储系统DIMM内存的几个问题

下面是客户咨询最多的几个关于EMC Unity的DIMM内存的问题,供大家参考。 1. Unity存储能否自己扩容内存 有客户觉得Unity存储的内容太小,想自己扩容内存,很朴实的想法,原来是每个控制器3条16gb,能不能升级到3条32gb或…

基于Mybatis-Plus拦截器实现MySQL数据加解密

一、背景 用户的一些敏感数据,例如手机号、邮箱、身份证等信息,在数据库以明文存储时会存在数据泄露的风险,因此需要进行加密, 但存储数据再被取出时,需要进行解密,因此加密算法需要使用对称加密算法。 常…

Unreal5 第三人称射击游戏 射击功能实现1

状态机的缓存 状态机缓存功能相当于我们只需要实现一次,可以在多个地方引用,也可以在别的状态机里面使用,而不是在里面再重新写一遍相应的功能。 我们可以在基础状态机的链接拉出一条线,搜索“缓存” 第一个就是新保存的缓存姿势…

Qt OpenGL(四十二)——Qt OpenGL 核心模式-GLSL(二)

提示:本系列文章的索引目录在下面文章的链接里(点击下面可以跳转查看): Qt OpenGL 核心模式版本文章目录 Qt OpenGL(四十二)——Qt OpenGL 核心模式-GLSL(二) 冯一川注:GLSL其实也是不断迭代的,比如像3.3版本中,基本数据类型浮点型只支持float型,而GLSL4.0版本开始就…

chatgpt赋能python:Python单位换算—让编程更精确的工具

Python单位换算—让编程更精确的工具 作为一名10年经验的Python工程师,我深深认识到在各种计算机领域的重要性。它可以帮助我们进行大量数据的计算和转换,其中的单位换算是其中一个重要的子领域。 单位换算对编程的重要性 无论是在科学研究还是工业生…

序贯最小二乘平差 VS 卡尔曼滤波

文章目录 Part.I IntroductionPart.II 概念比较Chap.I 序贯最小二乘平差Chap.II 卡尔曼滤波Chap.III 比较 Reference Part.I Introduction 序贯最小二乘平差和卡尔曼滤波有些相似,但是还是有一些区别: 序贯最小二乘平差用来处理静态数据,也…

层次多尺度注意力用于语义分割

层次多尺度注意力用于语义分割 HIERARCHICAL MULTI-SCALE ATTENTION FOR SEMANTIC SEGMENTATION https://arxiv.org/pdf/2005.10821.pdf 摘要 多尺度推断通常用于提高语义分割的结果。多个图像尺度通过网络传递,然后使用平均或最大池化方法将结果组合起来。在本文…