【深度学习】StableDiffusion的组件解析,运行一些基础组件效果

文章目录

  • 前言
  • vae
  • clip
  • UNet
  • unet训练
  • 帮助、问询

前言

看了篇文:

https://zhuanlan.zhihu.com/p/617134893

运行一些组件试试效果。

vae

代码:

import torch
from diffusers import AutoencoderKL
import numpy as np
from PIL import Image# 加载模型: autoencoder可以通过SD权重指定subfolder来单独加载
autoencoder = AutoencoderKL.from_pretrained("/ssd/xiedong/src_data/eff_train/Stable-diffusion/majicmixRealistic_v7_diffusers", subfolder="vae")
autoencoder.to("cuda", dtype=torch.float16)# 读取图像并预处理
raw_image = Image.open("girl.png").convert("RGB").resize((512, 512))
image = np.array(raw_image).astype(np.float32) / 127.5 - 1.0
image = image[None].transpose(0, 3, 1, 2)
image = torch.from_numpy(image)# 压缩图像为latent并重建
with torch.inference_mode():# latentx形状是 (B, C, H, W) 的张量  (1,4,64,64)latentx = autoencoder.encode(image.to("cuda", dtype=torch.float16)).latent_dist.sample()  # 压缩# 保存 latent 为 PNG 图像latent = latentx.permute(0, 2, 3, 1)  # 将 latent 重新排列为 (B, H, W, C) 格式latent = latent.cpu().numpy()  # 将 latent 转换为 NumPy 数组latent = (latent * 127.5 + 127.5).astype('uint8')  # 将值缩放到 [0, 255] 范围内,并转换为 uint8 类型latent = latent.squeeze(0)  # 去掉批次维度latent_image = Image.fromarray(latent)  # 将 NumPy 数组转换为 PIL Imagelatent_image.save("latent.png")  # 保存为 PNG 图像# shapeprint(latentx.shape)rec_image = autoencoder.decode(latentx).samplerec_image = (rec_image / 2 + 0.5).clamp(0, 1)rec_image = rec_image.cpu().permute(0, 2, 3, 1).numpy()rec_image = (rec_image * 255).round().astype("uint8")rec_image = Image.fromarray(rec_image[0])# save
rec_image.save("demo.png")

原图:

在这里插入图片描述

encoder之后:

在这里插入图片描述
decoder之后:

在这里插入图片描述

clip

在自然语言处理任务中,tokenizer和text_encoder是两个重要的组件,用于将文本转换为模型可以理解的数值表示形式。

  1. Tokenizer:

Tokenizer的作用是将一个文本序列(如句子或段落)分割成一系列的token(通常是单词或子词)。它将文本映射到一个词表(vocabulary),每个token对应词表中的一个索引(index)。在您的代码示例中,tokenizer将输入的文本"a photograph of an astronaut riding a horse"转换为对应的token id序列。

  1. Text Encoder:

Text Encoder(文本编码器)是一个预训练的语言模型,它可以将token id序列编码为对应的向量表示(embeddings)。这些向量表示捕获了单词及其上下文的语义信息。

在您的代码中:

  • tokenizer(prompt) 将文本"a photograph of an astronaut riding a horse"转换为对应的token id序列(如[1, 27, 38, 61, …]等)。
  • text_encoder(text_input_ids) 将这个token id序列输入到文本编码器模型中,得到对应的向量表示text_embeddings

最终得到的text_embeddings的形状是 torch.Size([1, 77, 768])。其中:

  • 1 表示批次大小(batch size),对于单个输入就是1。
  • 77 表示输入token的数量(由于padding,长度被填充到模型的最大长度)。
  • 768 是每个token的向量表示的维度。

通过这种编码方式,原始的文本被转换为了具有丰富语义信息的数值向量表示,方便被深度学习模型进一步处理。这种编码过程是自然语言处理中的常见做法。

from transformers import CLIPTextModel, CLIPTokenizertext_encoder = CLIPTextModel.from_pretrained("/ssd/xiedong/src_data/eff_train/Stable-diffusion/majicmixRealistic_v7_diffusers", subfolder="text_encoder").to("cuda")
# text_encoder = CLIPTextModel.from_pretrained("openai/clip-vit-large-patch14").to("cuda")
tokenizer = CLIPTokenizer.from_pretrained("/ssd/xiedong/src_data/eff_train/Stable-diffusion/majicmixRealistic_v7_diffusers", subfolder="tokenizer")
# tokenizer = CLIPTokenizer.from_pretrained("openai/clip-vit-large-patch14")# 对输入的text进行tokenize,得到对应的token ids
prompt = "a photograph of an astronaut riding a horse"
text_input_ids = tokenizer(prompt,padding="max_length",max_length=tokenizer.model_max_length,truncation=True,return_tensors="pt"
).input_idsprint(text_input_ids.shape)  # torch.Size([1, 77]
# 将token ids送入text model得到77x768的特征
text_embeddings = text_encoder(text_input_ids.to("cuda"))[0]
print(text_embeddings.shape)  # torch.Size([1, 77, 768])

UNet

稳定扩散(Stable Diffusion,SD)是一种基于扩散模型的生成式人工智能模型,用于创建图像。它的核心是一个860万参数的UNet结构,负责将文本提示转化为图像。

UNet结构主要由编码器(Encoder)和解码器(Decoder)两部分组成,两部分通过跳跃连接(Skip Connection)相连。编码器用于捕获输入的潜在表征(Latent Representation),解码器则根据这些表征生成最终图像。

具体而言,编码器包含:

  • 3个CrossAttnDownBlock2D模块,每个模块会对输入进行2倍下采样
  • 1个DownBlock2D模块,不进行下采样

中间是一个UNetMidBlock2DCrossAttn模块,用于连接编码器和解码器。

解码器包含:

  • 1个UpBlock2D模块
  • 3个CrossAttnUpBlock2D模块

编码器和解码器的模块数量和结构是对应的,通过跳跃连接融合不同尺度的特征。

在这里插入图片描述

CrossAttnDownBlock2D 和 CrossAttnUpBlock2D 是 Stable Diffusion 中 UNet 架构的关键模块,用于将文本条件(text condition)融入到图像生成的过程中。它们利用了自注意力(Self-Attention)机制,将文本嵌入与图像特征进行交叉注意力(Cross-Attention)操作。

以 CrossAttnDownBlock2D 为例,其核心是一个 CrossAttention 模块,该模块的工作原理如下:

  1. 将文本条件(如"一只可爱的小狗")编码为文本嵌入(text embeddings),记为 E t e x t \mathbf{E}_{text} Etext

  2. 从 UNet 的中间层获取图像特征,记为 F i m a g e \mathbf{F}_{image} Fimage

  3. 在 CrossAttention 中,将 F i m a g e \mathbf{F}_{image} Fimage 作为 Query,而 E t e x t \mathbf{E}_{text} Etext 作为 Key 和 Value,计算注意力权重:

    Attention ( Q , K , V ) = softmax ( Q K T d k ) V \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V Attention(Q,K,V)=softmax(dk QKT)V

    其中 Q = F i m a g e Q=\mathbf{F}_{image} Q=Fimage, K = E t e x t K=\mathbf{E}_{text} K=Etext, V = E t e x t V=\mathbf{E}_{text} V=Etext, d k d_k dk 是缩放因子。

  4. 将注意力权重与 F i m a g e \mathbf{F}_{image} Fimage 相加,得到融合了文本条件的新特征表示。

这个过程可以用以下伪代码表示:

class CrossAttention(nn.Module):def forward(self, x, context):"""x: 图像特征 [batch, channels, height, width]context: 文本嵌入 [batch, text_len, text_dim]"""q = x.view(x.size(0), -1, x.size(-1))  # [batch, channels*height*width, dim]k = context.permute(0, 2, 1)  # [batch, text_dim, text_len]v = context.permute(0, 2, 1)  # [batch, text_dim, text_len]attn = torch.bmm(q, k)  # [batch, channels*height*width, text_len]attn = attn / sqrt(k.size(-1))attn = softmax(attn, dim=-1)x = torch.bmm(attn, v)  # [batch, channels*height*width, text_dim]x = x.view(x.size(0), -1, x.size(-1))  # [batch, channels, height, width]return x

CrossAttnUpBlock2D 的工作方式与 CrossAttnDownBlock2D 类似,只是它位于 UNet 的解码器部分。通过这种交叉注意力机制,Stable Diffusion 能够将文本条件与图像特征进行融合,从而根据提示生成所需的图像。

CrossAttention 模块是 Stable Diffusion 中实现文本到图像生成的关键部分,它利用注意力机制将文本信息注入到图像特征中,使生成的图像能够匹配给定的文本描述。

unet训练

SD训练过程原理:

SD模型的训练过程可以概括为以下几个步骤:

  1. 将图像编码到潜在空间,获得潜在向量表示。
  2. 使用CLIP文本编码器获取文本的嵌入向量表示。
  3. 在潜在空间中采样噪声,并将其添加到潜在向量中,进行扩散过程。
  4. U-Net模型接收扩散后的噪声潜在向量和文本嵌入,预测原始的噪声向量。
  5. 计算预测噪声和实际噪声之间的均方误差作为损失函数。
  6. 通过反向传播优化U-Net模型参数,使其能够更好地预测噪声。

整个过程可以用以下公式表示:

L = E x 0 , ϵ , t [ ∥ ϵ − ϵ θ ( x t , t , y ) ∥ 2 ] \mathcal{L} = \mathbb{E}_{x_0, \epsilon, t} \left[\left\| \epsilon - \epsilon_\theta(x_t, t, y) \right\|^2\right] L=Ex0,ϵ,t[ϵϵθ(xt,t,y)2]

其中:

  • x 0 x_0 x0是原始的潜在向量
  • ϵ \epsilon ϵ是添加到潜在向量上的噪声
  • t t t是随机采样的时间步长
  • x t x_t xt是扩散后的噪声潜在向量
  • y y y是文本嵌入向量
  • ϵ θ \epsilon_\theta ϵθ是U-Net模型预测的噪声

通过最小化这个损失函数,U-Net模型可以学习到从噪声潜在向量和文本嵌入中预测原始噪声的能力。在生成图像时,可以通过从随机噪声开始,逐步去噪,并根据文本嵌入对每一步的去噪过程进行条件控制,最终得到符合文本描述的图像。

Classifier-Free Guidance (CFG)是一种在训练和生成过程中提高文本条件控制的技术。它的核心思想是在训练时,以一定概率随机丢弃文本嵌入,这样模型就可以同时学习条件预测和无条件预测。在生成时,将条件预测和无条件预测的结果进行加权融合,从而增强文本条件的影响。CFG可以用以下公式表示:

ϵ θ ( C F G ) = ϵ θ ( x t , t , y ) + s ⋅ ( ϵ θ ( x t , t , ∅ ) − ϵ θ ( x t , t , y ) ) \epsilon_\theta^{(CFG)} = \epsilon_\theta(x_t, t, y) + s \cdot (\epsilon_\theta(x_t, t, \emptyset) - \epsilon_\theta(x_t, t, y)) ϵθ(CFG)=ϵθ(xt,t,y)+s(ϵθ(xt,t,)ϵθ(xt,t,y))

其中:

  • ϵ θ ( x t , t , y ) \epsilon_\theta(x_t, t, y) ϵθ(xt,t,y)是条件预测的噪声
  • ϵ θ ( x t , t , ∅ ) \epsilon_\theta(x_t, t, \emptyset) ϵθ(xt,t,)是无条件预测的噪声
  • s s s是一个scale参数,用于控制条件和无条件预测的权重

通过CFG,可以有效地提高生成图像与输入文本的一致性。

帮助、问询

https://docs.qq.com/sheet/DUEdqZ2lmbmR6UVdU?tab=BB08J2

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

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

相关文章

[AIGC] Spring 获取前端请求参数的全面指南

在Spring框架中,我们有多种方式可以获取前端发来的请求参数。以下是一些常用的方法: 文章目录 1. 通过RequestParam注解2. 通过HttpServletRequest对象3. 通过PathVariable注解4. 通过ModelAndView对象5. 通过WebRequest对象 1. 通过RequestParam注解 使…

neo4j图数据库下载安装配置

neo4j下载地址Index of /doc/neo4j/3.5.8/ 1.说明:jdk 1.8 版本对应的 neo4j 数据库版本 推荐安装3.X版本 2.配置系统环境变量 3.启动 neo4j.bat console 4.访问

算法设计与分析(实验5)-----图论—桥问题

一.实验目的 掌握图的连通性。掌握并查集的基本原理和应用。 二.实验步骤与结果 1.定义 (1)图的相关定义 图:由顶点的有穷非空集合和顶点之间的边的集合组成。 连通图:在无向图G中,若对于…

为什么苹果 Mac 电脑需要使用清理软件?

尽管 Apple Mac 电脑因其卓越的性能、简洁高效的 macOS 操作系统及独特的美学设计备受全球用户青睐,但任何电子设备在长期使用后都难以避免面临系统资源日渐累积的问题。其中一个重要维护需求在于,随着使用时间的增长,Mac电脑可能会由于系统垃…

xss基础

第一关&#xff1a; html部分标签可以解析js <script>alert (1)</script> 第二关&#xff1a; 可以看到value用双引号闭合了&#xff0c;使用上一关的payload没用&#xff0c;尝试一下闭合这个input 所以使用双引号和>闭合后再加入上一关的payload 11"…

深入浅出 -- 系统架构之负载均衡Nginx缓存机制

一、Nginx缓存机制 对于性能优化而言&#xff0c;缓存是一种能够大幅度提升性能的方案&#xff0c;因此几乎可以在各处都能看见缓存&#xff0c;如客户端缓存、代理缓存、服务器缓存等等&#xff0c;Nginx的缓存则属于代理缓存的一种。对于整个系统而言&#xff0c;加入缓存带来…

机器学习(30)

文章目录 摘要一、文献阅读1. 题目2. abstract3. 网络架构3.1 Sequence Generative Adversarial Nets3.2 SeqGAN via Policy Gradient3.3 The Generative Model for Sequences3.4 The Discriminative Model for Sequences(CNN) 4. 文献解读4.1 Introduction4.2 创新点4.3 实验过…

GaN肖特基势垒二极管(SBD)的多阴极应用建模与参数提取

GaN Schottky Barrier Diode (SBD) Modeling and Parameter Extraction for Multicathode Application&#xff08;TED 24年&#xff09; 摘要 本文提出了一种适用于多阴极应用的紧凑型可扩展GaN肖特基二极管大信号模型。详细给出了外在和内在模型参数的可扩展规则。实验和理…

Tesseract 安装与配置及验证码识别

Tesseract 安装与配置 Tesseract 的使用&#xff0c;需要环境的支持&#xff0c;以实现简单的转换和训练。 1.环境 python版本&#xff1a;3.8.3 &#xff08;python2.7或3以上&#xff09; 操作系统&#xff1a;windows系统 2.Python安装 详见&#xff1a;Miniconda的…

ArcGIS Server 安装教程

​​​​​​​ 一、环境与文件准备 1.软件环境 已安装arcgis Desktop 10.2 2.安装及授权文件 二、安装步骤 1.下载安装包和授权文件&#xff0c;解压后打开ArcGIS Server10.2文件夹&#xff0c;打开ESRI.exe。 2.点击ArcGIS for Server后的Setup&#xff0c;开始安装。 3.…

【ArcGIS微课1000例】0108:ArcGIS计算归一化差值植被指数

本文讲解ArcGIS中,基于Landsat8数据的NDVI归一化差值植被指数计算。 文章目录 一、加载数据二、归一化植被指数NDVI1. NDVI介绍2. NDVI计算三、注意事项一、加载数据 加载配套数据0108.rar中的Landsat8的8个单波段数据,如下所示: Landsat8波段信息对照表如下表所示: 接下来…

Spring Security——09,解决跨域

解决跨域 一、SpringBoot配置二、配置SpringSecurity三、修改端口四、修改vue项目4.1 拿到token4.2 前端存储token4.3 前端请求头携带token 五、测试5.1 认证测试5.2 授权测试 一键三连有没有捏~~ 浏览器出于安全的考虑&#xff0c;使用 XMLHttpRequest对象发起 HTTP请求时必须…