当前位置: 首页 > news >正文

Stable Diffusion不同部件拆分详解!

前言

看到很多文章对Stable Diffusion各种原理、详解等,但是么有看到有文章细拆里面各个子模块在做啥,怎么做的,所以就会遇到整体原理理解很透传,问到细节就卡住,这段时间细看了一下文章,对各个部分做一个拆解详解。

Stable Diffusion由多个子网络组成,包括文本编码器、UNet和VAE三大部分。组合在一起可以看做一个接收文本输入,输出图像的模型。

所有的AI设计工具,模型和插件,都已经整理好了,👇获取~ 在这里插入图片描述

整体上看是一个接收文本输入,并输出图像的模型。Stable Diffusion处理的过程如下:

  1. 输入文本,使用CLIP模型对文本进行编码,获得文本Embedding

  2. 噪声输入VAE编码器,获取潜空间生成噪声Latent

  3. 将文本Embedding和Latent输入UNet模型,预测Latent中的噪声

  4. 去除Latent中的噪声,去除噪声后的结果重新赋值为Latent

  5. 重复步骤3、4直至噪声去除干净(step=30/50/1000等)

  6. 将Latent传入VAE解码器,得到最终生成图片

在整个网络训练过程当中,VAE编码器和解码器是在大量数据上预训练获取,CLIP Text Encoder使用大量的文本-图像对坐预训练,整个模型的核心是一个UNet噪声预测网络。不同于GAN直接从噪声中生成图片,Stable Diffusion会进行多次预测噪声并降噪,最终生成图片。

VAE

VAE模型在Diffusion Model里面并非必要的,因为Unet是可以直接接收图像输入,但是因为图像维度较高,增加计算量,训练效率降低,实际上VAE在Stable Diffusion中是作为一种提效的方法,减少了图片生成的资源需求。

VAE由Encoder和Decoder两个部分组成,首先需要输入x,经过Encoder编码后,得到(μ,σ),分别表示均值和方差,这两个变量可以确定一个分布,然后在当前分布中采样出样本z。z通常是一个比x维度更低的向量。采样出来的z输入Decoder,希望Decoder的输出x`与输入的x越接近越好。这样就达到了图像压缩的效果。

在训练Stable Diffusion时,会把图片输入VAE的Encoder,然后再拿来训练UNet,这样就可以在更低的维度空间训练图像生成模型,这样就可以减少资源的消耗。

问题就来了,VAE为什么能够作为图像恢复使用?

说到VAE就不得不先说一下AutoEncoder(AE:自编码器)

  • AE的Encoder是将图片映射成“数值编码”

  • Decoder是将“数值编码”映射成图片

这样存在的问题是,在训练过程中,随着不断降低输入图片与输出图片之间的误差,模型会过拟合,泛化性能不好。也就是说对于一个训练好的AE,输入固定的一张图片,就只会将其编码为确定的code,对于Decoder输入某个确定的code就只会输出某个确定的图片,并且如果这个code来自于没见过的图片,那么生成的图片也不会好。所以AE多用于数据的压缩和恢复,用于数据生成时效果并不理想。

那么VAE的为什么可以呢?实际上VAE不是将图片映射成“数值编码”,而将其映射成“分布”。举一个例子,假设人脸的属性只有6个维度[smile,skin tone, gender, beard,glasses,hair color],使用大型人脸数据集上训练了一个自编码器模型,理想的自编码器将学习人脸的描述性属性,如肤色、是否戴眼镜等,模型试图用一些压缩的表示来描述观,我们可能更倾向于将每个潜在属性表示为可能值的范围,比如概率在0~5之间认为是【笑】,其他是【不笑】。通过这种方法,我们现在将给定输入的每个潜在属性表示为概率分布。当从潜在状态解码时,我们将从每个潜在状态分布中随机采样,生成一个向量作为解码器模型的输入来得到对应的图像。

通过构造的编码器模型来输出可能值的范围(统计分布),我们将随机采样这些值以供给我们的解码器模型,我们实质上实施了连续,平滑的潜在空间表示。对于潜在分布的所有采样,期望解码器模型能够准确重构输入。因此,在潜在空间中彼此相邻的值应该与非常类似的重构相对应。

那也可以看出来,VAE的缺点是生成的数据不一定那么“真”,存在中间值,比如二分类猫狗数据,会存在一段概率分布在猫狗之间,那么解码器生成的图像会是即像猫又像狗,这也是现在SD等生图模型的结果会存在四不像。

Text Encoder CLIP

先看整体结构,是不是十分的清爽,简单明了。包括两个部分,即文本编码器(Text Encoder)和图像编码器(Image Encoder)。Text Encoder选择的是Text Transformer模型;Image Encoder选择了两种模型,一是基于CNN的ResNet(对比了不同层数的ResNet),二是基于Transformer的ViT

CLIP在文本-图像对数据集上的对比学习训练过程如下:

  1. 对于一个包含N个<文本-图像>对的训练batch,使用Text Encoder和Image Encoder提取N个文本特征和N个图像特征。

  2. 这里共有N个正样本,即真正属于一对的文本和图像(矩阵中的对角线元素),而剩余的文本-图像对皆为负样本。

  3. 将N个文本特征和N个图像特征两两组合,CLIP模型会预测出 N^2个可能的文本-图像对的相似度,这里的相似度直接计算文本特征和图像特征的余弦相似性(cosine similarity),即图中所示的矩阵。

  4. CLIP的训练目标就是最大化N个正样本的相似度,同时最小化N^2−N个负样本的相似度,即最大化对角线中蓝色的数值,最小化其它非对角线的数值

Image_features = image_encoder(I) #[n, d_i]  
Text_features = text_encoder(T) #[n, d_t]  # 对两个特征进行线性投射,得到相同维度的特征,并进行l2归一化  
Image_embedding = l2_normalize(np.dot(Image_features, W_i), axis=1)  
Text_embedding = l2_normalize(np.dot(Text_features, W_t), axis=1)  # 计算缩放的余弦相似度:[n, n]  
logits = np.dot(Image_embedding, Text_embedding.T) * np.exp(t)  # 对称的对比学习损失:等价于N个类别的cross_entropy_loss  
labels = np.arange(n) # 对角线元素的labels  
loss_i = cross_entropy_loss(logits, labels, axis=0)  
loss_t = cross_entropy_loss(logits, labels, axis=1)  
loss = (loss_i + loss_t)/2

思考题:CLIP的text Encoder为什么能在Stable Diffusion中用来做Unet的去噪Condition?

  • 文本直接输入网络需要转换为特征,其实现在有很多预训练好的文本编码器效果都很好,为什么当时优先选择了CLIP呢,大概率是因为CLIP的text Encoder在训练过程当中和图像进行了对齐,因为本身来讲图像和文本是两个域的数据,由于跨域之后一般不可比的原因,所以优先选择了CLIP,预训练时候已经把text和image做对齐,引起拿到对应的输入信息之后,可以类比为图像信息,对去噪进行增加,提高生成图像的效果。

  • CLIP的text Encoder较小,训练效率高

Unet

UNet模型在结构与VAE非常相似,也是Encoder-Decoder架构。在Stable Diffusion中,UNet作为一个噪声预测网络,在生图过程中需要进行多次推理,逐步预测当前step的噪声进行去噪,得到最终结果。首先不考虑VAE的介入,来看看UNet在Stable Diffusion中的作用。

实际上UNet在Stable Diffusion中充当噪声预测的功能。UNet接收一张带有噪声的图片,输出图片中的噪声,根据带噪声的图片和噪声我们可以得到加噪前的图片。这个降噪的过程通常会重复N遍。

知道UNet的作用后,就需要创建数据集了。输入只需要图片即可,拿到图片对该图片进行n次加噪,直到原图变成完全噪声。而加噪前的图片可以作为输入,加噪后的数据可以作为输出。如图所示:

在加噪的过程中,噪声逐步增大。因此在去噪的过程中,需要有噪声图片,以及当前加噪的step,然后预测对应的噪声进行去噪。下图是噪声预测部分的结构:

最后图像生成的步骤就是不停降噪的步骤:

最后,再加入VAE。加噪和预测噪声的步骤不再是作用在原图上,而是作用在VAE Encoder的输出上面,这样我们就可以在较小的图像(latents)上完成UNet的训练,极大减少资源的消耗。

loss是如何计算的:降噪过程中Unet是在学习噪声分布,loss是约束每次添加的噪声和网络输出的噪声之间的距离,即前向加噪过程可以得到样本和噪声标签,反向过程进行计算可以得到对应的loss。

这里分享给大家一份Adobe大神整理的《AIGC全家桶学习笔记》,相信大家会对AIGC有着更深入、更系统的理解。

有需要的朋友,可以点击下方免费领取!

在这里插入图片描述

AIGC所有方向的学习路线思维导图

这里为大家提供了总的路线图。它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。如果下面这个学习路线能帮助大家将AI利用到自身工作上去,那么我的使命也就完成了:
在这里插入图片描述

AIGC工具库

AIGC工具库是一个利用人工智能技术来生成应用程序的代码和内容的工具集合,通过使用AIGC工具库,能更加快速,准确的辅助我们学习AIGC
在这里插入图片描述

有需要的朋友,可以点击下方卡片免费领取!

在这里插入图片描述

精品AIGC学习书籍手册

书籍阅读永不过时,阅读AIGC经典书籍可以帮助读者提高技术水平,开拓视野,掌握核心技术,提高解决问题的能力,同时也可以借鉴他人的经验,结合自身案例融会贯通。

在这里插入图片描述

AI绘画视频合集

我们在学习的时候,往往书籍源码难以理解,阅读困难,这时候视频教程教程是就很适合了,生动形象加上案例实战,科学有趣才能更方便的学习下去。

在这里插入图片描述

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • nethogs显示每个进程所使用的带宽
  • Git可视化工具和基础命令
  • Linux 安装Docker
  • Linux实操笔记2 Ubuntu安装Nginx的不同方法
  • 阿里云人工智能ACP错题整理.txt
  • SQL编程题复习(24/9/19)
  • 【Geoserver使用】REST API调用(工作空间部分)
  • Python 装饰器使用详解
  • 腾讯大模型算法实习生面试题,大家秋招上岸
  • 【VUE3.0】动手做一套像素风的前端UI组件库---Button
  • SQL编程题复习(24/9/20)
  • 【随手笔记】使用J-LINK读写芯片内存数据
  • Java:List<String> 转换List<BigDecimal> 并求和
  • 【系统架构设计师】专业英语90题(附答案详解)
  • 手写Spring
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • 「前端」从UglifyJSPlugin强制开启css压缩探究webpack插件运行机制
  • 【JavaScript】通过闭包创建具有私有属性的实例对象
  • 【笔记】你不知道的JS读书笔记——Promise
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • 77. Combinations
  • ES6语法详解(一)
  • gulp 教程
  • JAVA_NIO系列——Channel和Buffer详解
  • node和express搭建代理服务器(源码)
  • text-decoration与color属性
  • 搞机器学习要哪些技能
  • 面试总结JavaScript篇
  • 前端面试题总结
  • 怎样选择前端框架
  • 栈实现走出迷宫(C++)
  • 正则学习笔记
  • 你对linux中grep命令知道多少?
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • ​卜东波研究员:高观点下的少儿计算思维
  • ​用户画像从0到100的构建思路
  • # wps必须要登录激活才能使用吗?
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • $.type 怎么精确判断对象类型的 --(源码学习2)
  • (3)llvm ir转换过程
  • (android 地图实战开发)3 在地图上显示当前位置和自定义银行位置
  • (NO.00004)iOS实现打砖块游戏(九):游戏中小球与反弹棒的碰撞
  • (附源码)计算机毕业设计SSM智能化管理的仓库管理
  • (力扣)1314.矩阵区域和
  • (十)Flink Table API 和 SQL 基本概念
  • (十八)devops持续集成开发——使用docker安装部署jenkins流水线服务
  • (实战)静默dbca安装创建数据库 --参数说明+举例
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (一)基于IDEA的JAVA基础1
  • (转)C语言家族扩展收藏 (转)C语言家族扩展
  • ***详解账号泄露:全球约1亿用户已泄露
  • .[hudsonL@cock.li].mkp勒索加密数据库完美恢复---惜分飞
  • .net core Redis 使用有序集合实现延迟队列
  • .NET Core工程编译事件$(TargetDir)变量为空引发的思考
  • .NET Core中Emit的使用