AI绘画中VAE压缩图像

介绍

在Stable Diffusion中,所有的去噪和加噪过程并非在图像空间直接进行,而是通过VAE模块将图像编码到一个低维空间。

这个低维空间的“分辨率”低于原始图像空间,有利于快速地完成加噪和去噪过程。

最后再将编码空间中的噪声表示解码恢复为图像空间,完成去噪或加噪操作。

采用这种编码-解码的流程,可以避免在高维图像空间直接操作带来的计算资源消耗,也更容易控制和操作噪声信号。

VAE模块承担了编码图像到隐空间然后操作的功能,是Stable Diffusion实现高效噪声增减的关键。

概念

变分自编码器(Variational Autoencoder, VAE)中的潜在空间(latent space)是一个核心概念,对理解 VAE 的工作原理至关重要。

潜在空间指的是一个较低维度的表示空间,在该空间中,数据的高维特性被编码为更为简洁的形式。在 VAE 框架中,潜在空间充当着数据的内部、抽象表示,通常捕获了数据的基本特征和结构。

在这里插入图片描述
在这个示例中:

  • “输入数据”是模型的输入,比如一张图像。
  • “编码器”将输入数据映射到潜在空间的分布参数,通常是均值(μ)和方差(σ)。
  • 在“潜在空间参数”步骤,从分布中“抽样”以产生潜在空间的样本点。
  • “解码器”接收潜在空间中的样本点,并尝试重构与原始输入类似的数据。
  • “重构数据”是模型的最终输出,是对输入数据的重构或生成版本。

潜在空间的重要性

  • 特征提取:在潜在空间中,数据的关键特征被提取和压缩,去除了冗余信息。
  • 数据生成:由于其连续性,潜在空间允许我们通过在其内进行抽样来生成新的数据实例,这些数据实例在某种程度上类似于原始数据集中的样本。
  • 数据表示:潜在空间提供了一种更加有效的方式来表示复杂数据,为数据的进一步分析和处理提供了可能。

历史

变分自编码器(Variational Autoencoder, VAE)的历史和演变可以概述为以下几个关键阶段:

  1. 初始发展(2013年左右)

    • VAE 的概念最初由 Kingma 和 Welling 在 2013 年的论文《Auto-Encoding Variational Bayes》中提出。https://arxiv.org/abs/1312.6114
    • 这一阶段的创新在于引入了一种新的生成模型框架,结合了深度学习与贝叶斯推断方法。VAE 提供了一种有效的方式来学习和推断复杂数据的潜在表示。
  2. 理论和应用的发展(2014-2016年)

    • 在这一时期,研究者开始深入探讨 VAE 的理论基础,包括其与传统自编码器的区别、潜在空间的属性以及优化技术。
    • 应用上,VAE 被用于图像生成、语音处理和推荐系统等多个领域,其能力在处理复杂数据分布时展现出显著优势。
  3. 结构和算法的创新(2017-2019年)

    • 随着深度学习技术的发展,VAE 的结构和算法得到了显著改进,如引入卷积神经网络(CNN)来处理图像数据,改善了模型的生成质量和效率。
    • 也出现了一些变体,如条件 VAE(CVAE)和序列变分自编码器(SVAE),这些变体扩展了 VAE 在特定场景下的应用。
  4. 集成和多模态学习(2020年至今)

    • VAE 开始与其他深度学习模型(如 GAN、Transformer)结合,形成更加复杂和强大的混合模型。
    • 在多模态学习领域,VAE 被用来融合不同类型的数据,如图像和文本,从而在生成任务中实现更丰富的表达能力。

架构

https://arxiv.org/abs/1312.6114

VAE 的核心是通过一个编码器将数据映射到潜在空间,然后通过一个解码器重构数据。在潜在空间中,数据的表示是基于随机分布的,通常是高斯分布。这种表示允许模型在生成新数据时捕捉输入数据的关键特征。

关于 VAE 的数学公式表达,它们主要围绕以下几个方面构建:

  1. 编码器的输出(Encoder Output)

    • 编码器将输入数据 ( x ) 映射到潜在空间中的一个分布,通常这个分布被假设为高斯分布,其参数是均值 ( μ ) ( \mu ) (μ) 和方差 ( σ 2 ) ( \sigma^2 ) (σ2)
    • 数学上表达为 q ϕ ( z ∣ x ) = N ( z ; μ , σ 2 I ) q_\phi(z|x) = \mathcal{N}(z; \mu, \sigma^2 I) qϕ(zx)=N(z;μ,σ2I),其中 ( ϕ ) ( \phi ) (ϕ) 是编码器的参数。
  2. 重构误差(Reconstruction Loss)

    • 这部分是通过解码器从潜在空间重构输入数据 ( x ) ( x ) (x) 时产生的误差。
    • 常用的度量方法是均方误差或交叉熵,具体取决于数据的性质。
  3. KL 散度(Kullback-Leibler Divergence)

    • KL 散度用于衡量编码器输出的分布 ( q ϕ ( z ∣ x ) ) ( q_\phi(z|x) ) (qϕ(zx)) 与先验分布 ( p ( z ) ) ( p(z) ) (p(z))(通常是标准高斯分布)之间的差异。
    • 公式为 KL [ q ϕ ( z ∣ x ) ∣ ∣ p ( z ) ] \text{KL}[q_\phi(z|x) || p(z)] KL[qϕ(zx)∣∣p(z)],这项帮助正则化潜在空间,防止过拟合。
  4. 变分下界(Variational Lower Bound, ELBO)

    • VAE 的目标是最大化每个输入 ( x ) ( x ) (x) 的证据下界(ELBO),其表达为: ELBO = E q ϕ ( z ∣ x ) [ log ⁡ p θ ( x ∣ z ) ] − KL [ q ϕ ( z ∣ x ) ∣ ∣ p ( z ) ] \text{ELBO} = \mathbb{E}_{q_\phi(z|x)}[\log p_\theta(x|z)] - \text{KL}[q_\phi(z|x) || p(z)] ELBO=Eqϕ(zx)[logpθ(xz)]KL[qϕ(zx)∣∣p(z)]
    • 这里 E q ϕ ( z ∣ x ) [ log ⁡ p θ ( x ∣ z ) ] \mathbb{E}_{q_\phi(z|x)}[\log p_\theta(x|z)] Eqϕ(zx)[logpθ(xz)] 是重构误差的期望, KL [ q ϕ ( z ∣ x ) ∣ ∣ p ( z ) ] \text{KL}[q_\phi(z|x) || p(z)] KL[qϕ(zx)∣∣p(z)] 是正则化项。

这些公式和原理共同构成了 VAE 的数学框架,使其成为一种强大的生成模型。在训练过程中,VAE 通过调整编码器和解码器的参数 ( ϕ ) ( \phi ) (ϕ) ( θ ) ( \theta ) (θ) 来最大化 ELBO,从而学习到有效的数据表示。

  • 优化目标:ELBO 是 VAE 训练过程中的优化目标,模型通过最大化 ELBO 来训练。

  • 平衡重构与正则化:ELBO 结合了两个重要部分——重构误差(数据的重构质量)和 KL 散度(潜在空间的正则化)。这种结合使模型在学习有效的数据表示的同时,避免了过拟合。

  • 提升数据生成质量:通过最大化 ELBO,VAE 能够更好地学习潜在空间中数据的分布,从而提高生成新数据样本的质量。
    在这里插入图片描述

import torch
import torch.nn as nn
import torch.nn.functional as Fclass Encoder(nn.Module):# 编码器定义def __init__(self, input_dim, hidden_dim, latent_dim):super(Encoder, self).__init__()self.linear1 = nn.Linear(input_dim, hidden_dim)self.mean = nn.Linear(hidden_dim, latent_dim)self.logvar = nn.Linear(hidden_dim, latent_dim)def forward(self, x):# 前向传播过程hidden = F.relu(self.linear1(x))mean = self.mean(hidden)logvar = self.logvar(hidden)return mean, logvarclass Decoder(nn.Module):# 解码器定义def __init__(self, latent_dim, hidden_dim, output_dim):super(Decoder, self).__init__()self.linear1 = nn.Linear(latent_dim, hidden_dim)self.linear2 = nn.Linear(hidden_dim, output_dim)def forward(self, z):# 前向传播过程hidden = F.relu(self.linear1(z))recon_x = torch.sigmoid(self.linear2(hidden))return recon_xclass VAE(nn.Module):# VAE模型定义def __init__(self, input_dim, hidden_dim, latent_dim):super(VAE, self).__init__()self.encoder = Encoder(input_dim, hidden_dim, latent_dim)self.decoder = Decoder(latent_dim, hidden_dim, input_dim)def reparameterize(self, mean, logvar):# 重参数化技巧std = torch.exp(0.5*logvar)eps = torch.randn_like(std)return mean + eps*stddef forward(self, x):# 定义模型的前向传播mean, logvar = self.encoder(x)z = self.reparameterize(mean, logvar)recon_x = self.decoder(z)return recon_x, mean, logvardef loss_function(self, recon_x, x, mean, logvar):# 定义损失函数BCE = F.binary_cross_entropy(recon_x, x, reduction='sum')KLD = -0.5 * torch.sum(1 + logvar - mean.pow(2) - logvar.exp())return BCE + KLD# 参数设定
input_dim = 784  # 例如MNIST数据的维度
hidden_dim = 400
latent_dim = 20# 初始化模型、优化器等
model = VAE(input_dim, hidden_dim, latent_dim)
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)# 训练过程
for epoch in range(num_epochs):model.train()train_loss = 0for batch_idx, (data, _) in enumerate(dataloader):optimizer.zero_grad()recon_batch, mean, logvar = model(data)loss = model.loss_function(recon_batch, data, mean, logvar)loss.backward()train_loss += loss.item()optimizer.step()print(f"Epoch {epoch}, Loss: {train_loss / len(dataloader.dataset)}")

使用

在这里插入图片描述
https://civitai.com/models/70248/color101-vae

from PIL import Image
import numpy as np
import torch
from diffusers import AutoencoderKL
import requests
from io import BytesIO# 设置设备并加载模型
device = 'cuda'
vae = AutoencoderKL.from_pretrained('runwayml/stable-diffusion-v1-5', subfolder='vae')
vae = vae.to(device)# 定义编码函数
def encode_img_latents(imgs):if not isinstance(imgs, list):imgs = [imgs]img_arr = np.stack([np.array(img) for img in imgs], axis=0)img_arr = img_arr / 255.0img_arr = torch.from_numpy(img_arr).float().permute(0, 3, 1, 2)img_arr = 2 * (img_arr - 0.5)latent_dists = vae.encode(img_arr.to(device))latent_samples = latent_dists.latent_dist.sample()latent_samples *= 0.18215return latent_samples# 定义解码函数
def decode_img_latents(latents):latents = 1 / 0.18215 * latentswith torch.no_grad():imgs = vae.decode(latents)imgs = (imgs.sample / 2 + 0.5).clamp(0, 1)imgs = imgs.detach().cpu().permute(0, 2, 3, 1).numpy()imgs = (imgs * 255).round().astype('uint8')pil_images = [Image.fromarray(image) for image in imgs]return pil_images# 拼接图像函数
def concat_image(im_list):img_number = len(im_list)if img_number == 0:return Nonedst = Image.new('RGB', (img_number * im_list[0].width, im_list[0].height))for idx, im in enumerate(im_list, 0):dst.paste(im, (idx * im.width, 0))return dst# 测试用例
pths = ["", ""]  # 替换为实际图像 URL
for pth in pths:response = requests.get(pth)img = Image.open(BytesIO(response.content)).convert('RGB')img = img.resize((256, 256))img_latents = encode_img_latents(img)dec_img = decode_img_latents(img_latents)[0]concat_image([img, dec_img]).show()  # 显示拼接的图像

VAE 与扩散模型

在这里插入图片描述

  • 原始图像通过VAE编码器编码到Latent空间
  • 在Latent空间添加噪声或去噪
  • Stable Diffusion模型接受去噪的隐变量和文本提示作为输入
  • 经过扩散过程生成新图像

VAE模块将图像表示到隐空间编码,以方便Stable Diffusion控制噪声过程。

  • 增强数据表示能力:VAE 的潜在空间提供了一种紧凑的数据表示,但可能不足以捕捉所有复杂的数据变化。通过扩散模型,可以在这个空间中进一步加入细节和多样性。

  • 改善生成质量:扩散模型能够生成极其逼真的图像。将这种能力应用于 VAE 的潜在空间,可以改善最终生成图像的质量。

  • 降低计算复杂性:在潜在空间上进行操作相比于直接在高维图像空间上处理,可以降低计算复杂性和提高效率。

  • 灵活性和创新:这种组合使用的方法展示了在深度学习和生成模型领域的创新和灵活性,通过不同技术的结合打开了新的可能性。

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

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

相关文章

【Element】el-table 使用 el-table-infinite-scroll 插件实现滚动加载

虽然 el 官方提供了 Infinite Scroll 无限滚动 组件 但是却不支持 el-table 组件,这就很难受了,还好已经有大佬写好了插件,并且支持 element-plus/infinite-scroll 组件的所有选项。 el-table-infinite-scroll el-table-infinite-scroll 看…

【数据结构入门精讲 | 第十二篇】考研408、公司面试树专项练习(一)

在上一篇文章中我们介绍了树的知识点,在这一篇中我们将进行树的专项练习。 目录 判断题选择题填空题二叉树的宽度R6-1 是否二叉搜索树 方法介绍: 已知中序及后序,求前序 如后序为DABEC,中序为DEBAC,求前序 则后序倒着写&#xff…

北京Modbus转Profinet网关的作用

背景:随着工业自动化的快速发展,各种仪器设备迅速崛起,但是在仪器出厂前需要很多的零部件来构建出需要的设备及功能,由于自动化设备的零部件不是统一生产商供应的,这样很容易出现某个零部件的通讯协议不匹配&#xff0…

搜索二叉树(超详解)

文章目录 前言查找搜索二叉树的结构insertfinderase递归版本Findinserterase 二叉树的拷贝问题搜索二叉树的应用Key模型Key/Value的模型 前言 普通二叉树其实意义不大, 如果用二叉树存储数据的话,还不如顺序表,链表这些。 搜索二叉树它的意义…

7.5组合总和②(LC40-M)

算法: 相比于上一题,数组candidates有重复元素,而要求不能有重复的组合,所以相对于39.组合总和 (opens new window)难度提升了不少。 如何去重? 先把candidates排序,让重复的元素都在一起 单层递归时&a…

MyBatis的关联查询!!!(一对一、一对多、多对多)

准备工作: 1.创建Maven工程,还没有配置Maven的和还不会的去看这里啦:maven的下载安装与配置环境变量!!!(全网最详细)-CSDN博客 Account.java : (pojo类) (这里我…

认识Linux背景

1.发展史 Linux从哪里来?它是怎么发展的?在这里简要介绍Linux的发展史 要说Linux,还得从UNIX说起 UNIX发展的历史 1968年,一些来自通用电器公司、贝尔实验室和麻省理工学院的研究人员开发了一个名叫Multics的特殊操作系统。Mu…

分布式锁常见问题及其解决方案

一、为什么要使用分布式锁? 因为在集群下,相当于多个JVM,就相当于多个锁,集群之间锁是没有关联的,会照成锁失效从而导致线程安全问题 分布式锁可以分别通过MySQL、Redis、Zookeeper来进行实现 二、redis分布式锁的实…

华为发布全闪备份一体机旗舰新品,并宣布备份软件开源

[中国,上海,2023年12月20日]在20日举行的OceanProtect数据保护新品发布会上,华为发布全闪备份一体机旗舰新品,并宣布备份软件开源,以应对智慧金融、自动驾驶等场景对数据备份效率及数据安全方面的新诉求,为…

工业信息采集平台的五大核心优势

关键字:工业信息采集平台,蓝鹏数据采集系统,蓝鹏测控系统, 生产管控系统, 生产数据处理平台,MES系统数据采集, 蓝鹏数据采集平台通过实现和构成其他工业数据信息平台的一级设备进行通讯,从而完成平台之间的无缝对接。这里我们采用的最多的方式是和PLC进行…

神经网络:深度学习基础

1.反向传播算法(BP)的概念及简单推导 反向传播(Backpropagation,BP)算法是一种与最优化方法(如梯度下降法)结合使用的,用来训练人工神经网络的常见算法。BP算法对网络中所有权重计算…

Redis取最近10条记录

有时候我们有这样的需求,就是取最近10条数据展示,这些数据不需要存数据库,只用于暂时最近的10条,就没必要在用到Mysql类似的数据库,只需要用redis即可,这样既方便也快! 具体取最近10条的方法&a…

Go 代码检查工具 golangci-lint

一、介绍 golangci-lint 是一个代码检查工具的集合,聚集了多种 Go 代码检查工具,如 golint、go vet 等。 优点: 运行速度快可以集成到 vscode、goland 等开发工具中包含了非常多种代码检查器可以集成到 CI 中这是包含的代码检查器列表&…

DBA-MySql面试问题及答案-上

文章目录 1.什么是数据库?2.如何查看某个操作的语法?3.MySql的存储引擎有哪些?4.常用的2种存储引擎?6.可以针对表设置引擎吗?如何设置?6.选择合适的存储引擎?7.选择合适的数据类型8.char & varchar9.Mysql字符集10.如何选择…

第九周算法题(哈希映射,二分,Floyd算法 (含详细讲解) )

第九周算法题 第一题 题目来源&#xff1a;33. 搜索旋转排序数组 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a;整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 <…

全网最全ChatGPT指令大全prompt

全网最全的ChatGPT大全提示词&#xff0c;大家可以进行下载。 AIGC ChatGPT 职场案例 AI 绘画 与 短视频制作 PowerBI 商业智能 68集 数据库Mysql 8.0 54集 数据库Oracle 21C 142集 Office 2021实战应用 Python 数据分析实战&#xff0c; ETL Informatica 数据仓库案例实战 E…

【JAVA面试题】什么是引用传递?什么是值传递?

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a; JAVA ⛳️ 功不唐捐&#xff0c;玉汝于成 前言 博客的正文部分可以详细介绍Java中参数传递的机制&#xff0c;强调Java是按值传递的&#xff0c;并解释了基本数据类型和对象引用在这种传…

二级分销的魅力:无限裂变创造十八亿的流水

有这么一个团队&#xff0c;仅靠这一个二级分销&#xff0c;六个月就打造了十八亿的流水。听着是不是很恐怖&#xff1f;十八亿确实是一个很大的数字&#xff0c;那么这个团队是怎么做到的呢&#xff1f;我们接着往下看。 这是一个销售减脂产品的团队。不靠网店&#xff0c;不…

【JMeter入门】—— JMeter介绍

1、什么是JMeter Apache JMeter是Apache组织开发的基于Java的压力测试工具&#xff0c;用于对软件做压力测试。它最初被设计用于Web应用测试&#xff0c;但后来扩展到其他测试领域。 &#xff08;Apache JMeter是100%纯JAVA桌面应用程序&#xff09; Apache JMeter可以用于对静…

pycharm git 版本回退

参考 https://blog.csdn.net/qq_38175912/article/details/102860195 yoyoketang 悠悠课堂