Stable Diffusion1.5网络结构-超详细原创

目录

1 Unet

1.1详细整体结构

1.2 缩小版整体结构

1.3 时间步编码

1.4 CrossAttnDownBlock2D

1.4.1 ResnetBlock2D

1.4.2 Transformer2DModel

1.4.2.1 BasicTransformerBlock

1.4.2.1.1 SelfAttention

1.4.2.1.2 CrossAttention

1.4.2.1.3 FeedForward

1.4.3 DownSample2D

1.5 DownBlock2D

1.6 UnetMidBlock2DCrossAttn

1.7 UpBlock2D

1.7.1 UpSample2D

1.8 CrossAttnUpBlock2D

2 VAE

3 CLIP


绘制软件:ProcessOn,以下图片保存可高清查看

1 Unet

1.0 介绍 

        负责预测噪声

1.1详细整体结构

1.2 缩小版整体结构

1.3 时间步编码

1.4 CrossAttnDownBlock2D

每个ResnetBlock2D的输入有两个

1,一个是来自上一层的输出lattent,

2,另一个来自时间步编码模块的输出time_embeds ( shape=[2, 1280], 后面省略说明,默认[2, 1280]这种写法是tersor的形状)

每个Transformer2DModel输入有两个

1,上一层的输出

2, CLIP text_encoder的文本编码text embedding,或者叫提示词编码prompt embedding,其shape=[2, 77, 768]

后面凡是有ResnetBlock2D和Transformer2DModel的模块,其输入形式都是如此,为了方便,后面有些模块的time_embeds和prompt  embedding这两个输入就默认不画了,例如UnetMidBlock2DCrossAttn、UpBlock2D、CrossAttnUpBlock2D

1.4.1 ResnetBlock2D

需要注意的点

1, ResnetBlock2D的输入有两个,一个是来自上一层的lattent,另一个来自时间步编码模块的输出time_embeds ( shape=[2, 1280], 后面省略说明,默认[2, 1280]这种写法是tersor的形状)

2, Conv3x3和Linear的输入输出Channel,不同层会不一样

3, 输入输出通道数不一致的时候,残差连接会用一个1x1的卷积

1.4.2 Transformer2DModel

Transformer2DModel输入有两个

1,上一层的输入

2, CLIP text_encoder的文本编码text embedding,或者叫提示词编码prompt embedding,其shape=[2, 77, 768]

1.4.2.1 BasicTransformerBlock

1.4.2.1.1 SelfAttention

1.4.2.1.2 CrossAttention

1.4.2.1.3 FeedForward

1.4.3 DownSample2D

1.5 DownBlock2D

1.6 UnetMidBlock2DCrossAttn

1.7 UpBlock2D

UNet右边部分的ResnetBlock2D模块,其输入除了有来自上一层的输出和time_embedd之外,还有自UNet左边部分输入,具体做法是将上一层的输出和UNet左边部分输入进行concat之后送进ResnetBlock2D模块,然后和time_embedd相加,后面的CrossAttnUpBlock2D也是如此,具体查看1.1 详细整体结构

1.7.1 UpSample2D

1.8 CrossAttnUpBlock2D

注意, 最后一个CrossAttnUpBlock2D没有UpSample2D模块,该模块具体输入输出shape看1.1 详细整体结构

2 VAE

2.0 介绍

将扩散过程从512x512的图像空间映射降维到64x64的潜空间,内存和运算量减小64倍

2.1 AE

注意:下面说的特征向量,编码向量,潜变量,code是同一个意思

普通的自编码器,分为编码器和解码器,编码器Encoder负责将编码图像,把图像从高维映射到低维,得到特征向量,例如把3x512x512的图像编码成4x64x64的特征向量,这个特征向量可以表示原始图像,包含原始图像的特征,比如颜色,纹理等其他抽象特征,解码器Decoder负责把低维的特征向量还原回原始图像.但这种编码是固定的,一张图片只能编码成一个固定的向量,反过来,解码也是唯一的,一个固定的编码向量只会被解码成一张确定的图像,如果来一张你训练集没见过的图片,对其编码后再解码,生成的图像大概率是个无意义的图像,因此AE是一个单值映射关系,潜变量(即编码向量)具有不连续性,潜变量是确定性值,选择一个随机的潜在变量可能会产生垃圾输出,潜在空间缺乏生成能力(即潜空间不是所有的潜变量都是有效的),

举个李宏毅老师的例子:

假设我们训练好的AE将“新月”图片encode成code=1(这里假设code只有1维),将其decode能得到“新月”的图片;将“满月”encode成code=10,同样将其decode能得到“满月”图片。这时候如果我们给AE一个code=5,我们希望是能得到“半月”的图片,但由于之前训练时并没有将“半月”的图片编码,或者将一张非月亮的图片编码为5,那么我们就不太可能得到“半月”的图片。

其他博客解释:

        AE的Encoder是将图片映射成“数值编码”,Decoder是将“数值编码”映射成图片。这样存在的问题是,在训练过程中,随着不断降低输入图片与输出图片之间的误差,模型会过拟合,泛化性能不好。也就是说对于一个训练好的AE,输入某个图片,就只会将其编码为某个确定的code,输入某个确定的code就只会输出某个确定的图片,并且如果这个code来自于没见过的图片,那么生成的图片也不会好。

        自动编码器是数据相关的(data-specific 或 data-dependent),这意味着自动编码器只能压缩那些与训练数据类似的数据,反过也是一类数据对应一种编码器,无法拓展一种编码器去应用于另一类数据。

2.2 VAE

而VAE不是将图像编码成一个固定的值,而是编码成一个连续的分布,这样,只要满足这个分布,我就能重建原始图像,满足这个分布的值会有很多,不再是一个固定的code了,例如,我把编码器的输出约束成一个标准正态分布,重建图像我只需要从标准正态分布采样在送到就解码器即可,

这里其实不一定非得要是标准正态分布,只要是连续的分布理论上都可以,但由于标准正态分布有良好的性质:1,高维正态分布采样的向量模长近似一致,两两近似正交,两点之间的欧式距离与期望值近似,这是一个很好的约束,对模型的学习有利;2,良好的数学性质,但你对多个分布进行运算时(像Diffusion),正态分布会带来很大的便利,可以通过标准化,变换等方式处理,便于模型的训练和优化;3,用标准正态分布对潜变量进行建模,能利用正态分布的性质进行随机采样和重构(重参数化)

举个例子:来自https://www.cnblogs.com/amazingter/p/14686450.html

针对上面的半月问题,我们转变思路,不将图片映射成“数值编码”,而将其映射成“分布”。我们将“新月”图片映射成μ=1的正态分布,那么就相当于在1附近加了噪声,此时不仅1表示“新月”,1附近的数值也表示“新月”,只是1的时候最像“新月”。将"满月"映射成μ=10的正态分布,10的附近也都表示“满月”。那么code=5时,就同时拥有了“新月”和“满月”的特点,那么这时候decode出来的大概率就是“半月”了。这就是VAE的思想。

关于VAE还可以参考【VAE学习笔记】全面通透地理解VAE(Variational Auto Encoder)_vae的作用-CSDN博客

写的很好,接下来正式上图

2.3 整体结构 

由于csdn查看大图很捞,可双击另存为查看高清大图

2.4 DownEncoderBlock2D

注意:VAE的ResnetBlock2D模块是没有时间步的输入的,即time_embeds=None, 其他的和上面Unet中的ResnetBlock2D一致

2.4.1  ResnetBlock2D

2.4.2 UpSample2D

2.5 UnetMidBlock2D

SelfAttention参考Unet中的

2.6 Sample

重参数化技巧:

现在均值mean和方差var(实际是log方差,这里先以方差为例)是网络的输出,也就是现在编码器的输出服从N~(mean, var)这个正态分布,我们要从这个正态分布采样出一个样本,送进解码器,这个样本是服从N~(mean, var)正态分布的,但采样这个操作是不可导的,采样操作是指从某个概率分布中随机抽取样本的过程,因为梯度是损失函数关于模型参数的变化率,而采样操作的非确定性使得无法直接计算关于参数的精确梯度。如果将采样操作视为一个具有参数的函数,并尝试计算其导数,通常会遇到两个问题:

  1. 不可导性: 由于采样操作引入了离散性和不可导性,它们在大多数情况下是不可导的。导数描述的是函数在某一点上的变化率,而采样操作在这方面表现得很突变和不连续,因此没有明确定义的导数。

  2. 梯度的方差: 即使我们忽略不可导性,尝试使用梯度信息来更新参数,由于采样引入的随机性,梯度的方差可能会非常高,导致不稳定的优化过程。

所以无法对mean和var求偏导,因为这里mean和var就是网络的参数,这个时候可以从标准正态分布N(0,1)采样一个sample(一般会用概率密度的分布函数去采样), 这个时候sample就是一个确定的值,把sample当成常数,std是标准差,等于var开根号

令z=mean + sample * std,这个时候z就可以对mean和std求偏导了,z就等价从N~(mean, var)这个分布采样,可以对z求期望和方差,根据高斯分布的性质以及期望和方差的公式,能得出z也服从正态分布,切均值=mean, 方差=std的平方=var,这样做其实是把随机性转移到了sample这个常数

但代码里是log方差,是因为方差是正的,加log让它取值范围也能取负值,这样就不用加激活函数了,所以后面再用exp还原方差

2.7 UpDecoderBlock2D

 2.7.1  UpSample2D

3 CLIP

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

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

相关文章

【数据库】数据库连接池导致系统吞吐量上不去-复盘

在实际的开发中,我们会使用数据库连接池,但是如果不能很好的理解其中的含义,那么就可以出现生产事故。 HikariPool-1 - Connection is not available, request timed out after 30001ms.当系统的调用量上去,就出现大量这样的连接…

Git 基本操作

目录 创建仓库命令 git init git clone 提交与修改 git add git status git diff git commit git reset git rm git mv git checkout git switch git restore 提交日志 git log git blame 远程操作 git remote git fetch git pull git push Git 的工作就…

Redis维护缓存的方案选择

Redis中间件常常被用作缓存,而当使用了缓存的时候,缓存中数据的维护,往往是需要重点关注的,尤其是重点考虑的是数据一致性问题。以下是维护数据库缓存的一些常用方案。 1、先删除缓存,再更新数据库 导致数据不一致的…

如何实现Redisson分布式锁

首先,不要将分布式锁想的太复杂,如果我们只是平时业务中去使用,其实不算难,但是很多人写的文章不能让人快速上手,接下来,一起看下Redisson分布式锁的快速实现 Redisson 是一个在 Redis 的基础上实现的 Java…

机器学习第4天:模型优化方法—梯度下降

文章目录 前言 梯度下降原理简述 介绍 可能的问题 批量梯度下降 随机梯度下降 基本算法 存在的问题 退火算法 代码演示 小批量梯度下降 前言 若没有机器学习基础,建议先阅读同一系列以下文章 机器学习第1天:概念与体系漫游-CSDN博客 机器学习…

802.11-2020协议学习__专题__TxTime-Calculation__HR/DSSS

802.11-2020协议学习__专题__TxTime-Calculation__HR/DSSS 16.2.2 PPDU format16.2.2.1 General16.2.2.2 Long PPDU format16.2.2.3 Short PPDU format 16.3.4 HR/DSSS TXTIME calculation PREV: TBD NEXT: TBD 16.2.2 PPDU format 16.2.2.1 General 定…

五分钟,Docker安装kafka 3.5,kafka-map图形化管理工具

首先确保已经安装docker,如果是windows安装docker,可参考 wsl2安装docker 1、安装zk docker run -d --restartalways -e ALLOW_ANONYMOUS_LOGINyes --log-driver json-file --log-opt max-size100m --log-opt max-file2 --name zookeeper -p 2181:218…

各类软件docker安装

docker Docker 要求 CentOS 系统的内核版本高于 3.10 ,通过 uname -r 命令查看你当前的内核版本: uname -r 3.10.0-1062.1.2.el7.x86_64 安装 Docker: 安装 Docker:yum -y install dockerkafka和zookeeper docker pull wurstmei…

【RH850芯片】RH850U2A芯片平台Spinlock的底层实现

目录 前言 正文 1.RH850U2A上的原子操作 1.1 Link 1.2 Link generation 1.3 Success in storing 1.4 Failure in storing 1.5 Condition for successful storing 1.6 Loss of the link 1.7 示例代码 2.Spinlock代码分析 2.1 尝试获取Spinlock 2.2 释放Spinlock …

Vue前端添加水印功能

文章目录 概要技术细节附上几张调整的结果图 概要 前端Vue在页面添加水印,且不影响页面其他功能使用,初级代码水准即可使用,且有防人修改或者删除功能! 提示:适用于Vue,组件已经封装开箱即用,有…

OpenHarmony应用开发入门教程(一、开篇)

前言 华为正式宣布2024年发布的华为鸿蒙OS Next版将不再兼容安卓系统。这一重大改变,预示着华为鸿蒙OS即将进入一个全新的阶段。 都说科技无国界,这是骗人的鬼话。谷歌的安卓12.0系统早已发布,但是自从受到美影响,谷歌就拒绝再向…

CAD长方形纤维插件2D

插件介绍 CAD长方形纤维插件2D版本可用于在AutoCAD软件内生成随机分布的长方形纤维图形,生成的dwg格式模型可用于模拟二维随机分布的纤维复合材料、随机初始裂缝等,同时模型可导入COMSOL、Abaqus、ANSYS、Fluent等有限元软件内进行仿真分析计算。 插件…

【算法萌新闯力扣】:找到所有数组中消失对数字

力扣热题:找到所有数组中消失对数字 开篇 这两天刚交了蓝桥杯的报名费,刷题的积极性高涨。算上打卡题,今天刷了10道算法题了,题目都比较简单,挑选了一道还不错的题目与大家分享。 题目链接:448.找到所有数组中消失对…

(二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、数据集二、导入数据以及展示部分1.导入数据集以及对数据集进行处理2.展示数据(看看就好) 三(1)、搭建网络进…

ubuntu 20.04安装 Anaconda教程

在安装Anaconda之前需要先安装ros(防止跟conda冲突,先装ros)。提前安装好cuda 和cudnn。 本博客参考:ubuntu20.04配置ros noetic和cuda,cudnn,anaconda,pytorch深度学习的环境 安装完conda后,输入: pyth…

Flink(六)【DataFrame 转换算子(下)】

前言 今天学习剩下的转换算子:分区、分流、合流。 每天出来自学是一件孤独又充实的事情,希望多年以后回望自己的大学生活,不会因为自己的懒惰与懈怠而悔恨。 回答之所以起到了作用,原因是他们自己很努力。 …

人工智能基础_机器学习036_多项式回归升维实战3_使用线性回归模型_对天猫双十一销量数据进行预测_拟合---人工智能工作笔记0076

首先我们拿到双十一从2009年到2018年的数据 可以看到上面是代码,我们自己去写一下 首先导包,和准备数据 from sklearn.linear_model import SGDRegressor import numpy as np import matplotlib.pyplot as plt X=np.arange(2009.2020)#左闭右开,2009到2019 获取从2009到202…

MIKE水动力笔记20_由dfs2网格文件提取dfs1断面序列文件

本文目录 前言Step 1 MIKE Zero工具箱Step 2 提取dfs1 前言 在MIKE中,dfs2是一个一个小格格的网格面的时间序列文件,dfs1是一条由多个点组成的线的时间序列文件。 如下两图: 本博文内容主要讲如何从dfs2网格文件中提取dfs1断面序列文件。 …

CI/CD -gitlab

目录 一、常用命令 二、部署 一、常用命令 官网:https://about.gitlab.com/install/ gitlab-ctl start # 启动所有 gitlab 组件 gitlab-ctl stop # 停止所有 gitlab 组件 gitlab-ctl restart # 重启所有 gitlab 组件 gitlab-ctl statu…

linux进程间通信之信号

摘要 本文旨在研究Linux进程间通信的机制之一:信号。信号是由操作系统来处理的,说明信号的处理在内核态。信号不一定会立即被处理,此时会储存在信 号的信号表中。最后,我们会对这种通信方式的优缺点进行全面的分析,并给…