变分自编码器(Variational AutoEncoder,VAE)

这篇具有很好参考价值的文章主要介绍了变分自编码器(Variational AutoEncoder,VAE)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1 从AE谈起

说到编码器这块,不可避免地要讲起AE(AutoEncoder)自编码器。它的结构下图所示:

变分自编码器(Variational AutoEncoder,VAE),深度学习相关算法学习,人工智能,深度学习,stable diffusion,DALL·E 2,Imagen
据图可知,AE通过自监督的训练方式,能够将输入的原始特征通过编码encoder后得到潜在的特征编码,实现了自动化的特征工程,并且达到了降维和泛化的目的。而后通过对进行decoder后,我们可以重构输出。一个良好的AE最好的状态就是解码器的输出能够完美地或者近似恢复出原来的输入, 即。为此,训练AE所需要的损失函数是: ∣ ∣ x − x ^ ∣ ∣ ||x-\hat{x}|| ∣∣xx^∣∣

AE的重点在于编码,而解码的结果,基于训练目标,如果损失足够小的话,将会与输入相同。从这一点上看解码的值没有任何实际意义,除了通过增加误差来补充平滑一些初始的零值或有些许用处。

易知,从输入到输出的整个过程,AE都是基于已有的训练数据的映射,尽管隐藏层的维度通常比输入层小很多,但隐藏层的概率分布依然只取决于训练数据的分布,这就导致隐藏状态空间的分布并不是连续的,它只是稀疏地记录下来你的输入样本和生成图像的一一对应关系。 因此如果我们随机生成隐藏层的状态,那么它经过解码将很可能不再具备输入特征的特点,因此想通过解码器来生成数据就有点强模型所难了

如下图所示,仅通过AE,我们在码空间里随机采样的点并不能生成我们所希望的相应图像。这就使得我的不能够达到AIGC的效果。
变分自编码器(Variational AutoEncoder,VAE),深度学习相关算法学习,人工智能,深度学习,stable diffusion,DALL·E 2,Imagen
据此,我们对AE的隐藏层z作出改动(让隐空间连续光滑),得到了VAE。
变分自编码器(Variational AutoEncoder,VAE),深度学习相关算法学习,人工智能,深度学习,stable diffusion,DALL·E 2,Imagen

变分自编码器(Variational AutoEncoder,VAE),深度学习相关算法学习,人工智能,深度学习,stable diffusion,DALL·E 2,Imagen

2 变分自编码器(Variational AutoEncoder,VAE)

关于变分推断,请查看本人的另一篇博文:变分推断(Variational Inference)

这里只做一个总结:

  • 变分推断是使用另一个分布 q ( z ) q(z) q(z)近似 p ( z ∣ x ) p(z|x) p(zx)
  • 用KL距离衡量分布的近似程度: K L ( q ( z ) ∣ ∣ p ( z ∣ x ) ) KL(q(z)||p(z|x)) KL(q(z)∣∣p(zx)),所以最优的 q ∗ ( z ) = a r g m i n q ( z ) ∈ Q K L ( q ( z ) ∣ ∣ p ( z ∣ x ) ) q^*(z)=argmin_{q(z) \in Q}KL(q(z)||p(z|x)) q(z)=argminq(z)QKL(q(z)∣∣p(zx))
  • K L ( q ( z ) ∣ ∣ p ( z ∣ x ) ) KL(q(z)||p(z|x)) KL(q(z)∣∣p(zx))的最小化转化为对ELBO的最大化,也就是 q ∗ ( z ) = a r g m i n q ( z ) ∈ Q K L ( q ( z ) ∣ ∣ p ( z ∣ x ) ) = a r g m a x q ( z ) ∈ Q E L B O = a r g m a x q ( z ) ∈ Q E q ( l o g ( p ( x , z ) − l o g q ( z ) ) ) q^*(z)=argmin_{q(z) \in Q}KL(q(z)||p(z|x))=argmax_{q(z)\in Q}ELBO=argmax_{q(z)\in Q}E_q(log(p(x,z)-logq(z))) q(z)=argminq(z)QKL(q(z)∣∣p(zx))=argmaxq(z)QELBO=argmaxq(z)QEq(log(p(x,z)logq(z)))

VAE全称是Variational AutoEncoder,即变分自编码器。

在VAE中 q ( z ) q(z) q(z)用一个编码器神经网络表示,假如其参数是 θ \theta θ,那么我们用 q θ ( z ) q_{\theta}(z) qθ(z)或者 q θ ( z ∣ x ) q_{\theta}(z|x) qθ(zx)表示。 p ( z ∣ x ) p(z|x) p(zx)可以认为是自然界真实存在的一个概率分布,但是我们不知道,所以需要用一个神经网络把他近似出来。

2.1 VAE的目的

变分自编码器(Variational AutoEncoder,VAE),深度学习相关算法学习,人工智能,深度学习,stable diffusion,DALL·E 2,Imagen
VAE的目的:
(1)用神经网络去逼近和模拟 p ( z ∣ x ) p(z|x) p(zx)近似 p ( x ∣ z ) p(x|z) p(xz)这两个概率分布
(2)并尽量保证隐空间是连续和平滑的,即 p ( z ) p(z) p(z) p ( z ∣ x ) p(z|x) p(zx)是平滑的

2.2 VAE方法与损失函数

作者方法“
(1)定义: p ( z ) ∼ N ( 0 , 1 ) p(z) \sim N(0,1) p(z)N(0,1)
(2)定义: q θ ( z ∣ x ) ∼ N ( g ( x ) , h ( x ) ) q_{\theta}(z|x) \sim N(g(x),h(x)) qθ(zx)N(g(x),h(x)),也就是 q θ ( z ∣ x ) q_{\theta}(z|x) qθ(zx)的期望和方差是用两个神经网络计算出来的
(3)定义: p θ ′ ( x ∣ z ) ∼ N ( f ( z ) , c I ) p_{\theta'}(x|z) \sim N(f(z),cI) pθ(xz)N(f(z),cI),所以解码器的输出的是 p θ ′ ( x ∣ z ) p_{\theta'}(x|z) pθ(xz)的期望
这样直接定义好吗?为这么直接这样定义出来?看下面的一个slide
变分自编码器(Variational AutoEncoder,VAE),深度学习相关算法学习,人工智能,深度学习,stable diffusion,DALL·E 2,Imagen
对ELBO做一个推导:
变分自编码器(Variational AutoEncoder,VAE),深度学习相关算法学习,人工智能,深度学习,stable diffusion,DALL·E 2,Imagen

因为 p ( x ∣ z ) = 1 2 π c e ∣ ∣ x − f ( z ) ∣ ∣ 2 2 c p(x|z) = \frac{1}{\sqrt{2\pi c}}e^{\frac{||x-f(z)||^2}{2c}} p(xz)=2πc 1e2c∣∣xf(z)2,所以有:
变分自编码器(Variational AutoEncoder,VAE),深度学习相关算法学习,人工智能,深度学习,stable diffusion,DALL·E 2,Imagen
也就是找到这样的三个神经网络使得上面的式子最大。
对于上面的第二项:
变分自编码器(Variational AutoEncoder,VAE),深度学习相关算法学习,人工智能,深度学习,stable diffusion,DALL·E 2,Imagen
所以损失函数可以写成:
l o s s = 1 2 ( − l o g h ( x ) 2 + h ( x ) 2 + g ( x ) 2 − 1 ) + C ∣ ∣ x − f ( z ) ∣ ∣ 2 loss=\frac{1}{2}(-logh(x)^2+h(x)^2+g(x)^2-1)+C||x-f(z)||^2 loss=21(logh(x)2+h(x)2+g(x)21)+C∣∣xf(z)2

2.3 重参数技巧

从高斯分布 N ( μ , σ ) N(μ,σ) N(μ,σ)中采样的操作被巧妙转换为了从 N ( 0 , 1 ) N(0,1) N(0,1)中采样得到 ϵ ϵ ϵ后,再通过 z = μ + σ × ϵ z=μ+σ \times ϵ z=μ+σ×ϵ变换得到。
变分自编码器(Variational AutoEncoder,VAE),深度学习相关算法学习,人工智能,深度学习,stable diffusion,DALL·E 2,Imagen
而在重参数后,我们计算反向传播的过程 如下图所示:

变分自编码器(Variational AutoEncoder,VAE),深度学习相关算法学习,人工智能,深度学习,stable diffusion,DALL·E 2,Imagen

2.4 整合起来

变分自编码器(Variational AutoEncoder,VAE),深度学习相关算法学习,人工智能,深度学习,stable diffusion,DALL·E 2,Imagen

(1)从样本库中取图片x
(2)g(x)计算均值,h(x)计算方差,从标准正太分布中采样一个数 ζ \zeta ζ,然后计算 z = ζ h ( x ) + g ( x ) z=\zeta h(x)+g(x) z=ζh(x)+g(x),然后计算 f ( z ) f(z) f(z)
(3)计算损失
(4)反向传播

3 代码实现

3.1 VAE.py

import  torch
from    torch import nn
 
 
class VAE(nn.Module): 
    def __init__(self):
        super(VAE, self).__init__() 
 
        # [b, 784] =>[b,20]
        # u: [b, 10]
        # sigma: [b, 10]
        self.encoder = nn.Sequential(
            nn.Linear(784, 256),
            nn.ReLU(),
            nn.Linear(256, 64),
            nn.ReLU(),
            nn.Linear(64, 20),
            nn.ReLU()
        )
 
        # [b,10] => [b, 784]
        # sigmoid函数把结果压缩到0~1
        self.decoder = nn.Sequential(
            nn.Linear(10, 64),
            nn.ReLU(),
            nn.Linear(64, 256),
            nn.ReLU(),
            nn.Linear(256, 784),
            nn.Sigmoid()
        )
 
    def forward(self, x):
        """
        :param x:
        :return:
        """
        batchsz = x.size(0)
        # flatten
        x = x.view(batchsz, 784)
        # encoder
        # [b, 20], including mean and sigma
        h_ = self.encoder(x)
        # chunk 在第二维上拆分成两部分
        # [b, 20] => [b,10] and [b, 10]
        mu, sigma = h_.chunk(2, dim=1)
        # reparametrize tirchk, epison~N(0, 1)
        # torch.randn_like(sigma)表示正态分布
        h = mu + sigma * torch.randn_like(sigma)
 
        # decoder
        x_hat = self.decoder(h)
        # reshape
        x_hat = x_hat.view(batchsz, 1, 28, 28)
 
        # KL
        # 1e-8是防止σ^2接近于零时该项负无穷大
        # (batchsz*28*28)是让kld变小
        kld = 0.5 * torch.sum(
            torch.pow(mu, 2) +
            torch.pow(sigma, 2) -
            torch.log(1e-8 + torch.pow(sigma, 2)) - 1
        ) / (batchsz*28*28)
 
 
        return x, kld

3.2 main.py

import  torch
from    torch.utils.data import DataLoader
from    torch import nn, optim
from    torchvision import transforms, datasets
 
from    ae_1 import AE
from    vae import VAE
from    vq-vae import VQVAE
 
import  visdom
 
def main():
    mnist_train = datasets.MNIST('mnist', True, transform=transforms.Compose([
        transforms.ToTensor()
    ]), download=True)
    mnist_train = DataLoader(mnist_train, batch_size=32, shuffle=True)
 
    mnist_test = datasets.MNIST('mnist', False, transform=transforms.Compose([
        transforms.ToTensor()
    ]), download=True)
    mnist_test = DataLoader(mnist_test, batch_size=32, shuffle=True)
 
    #无监督学习,不能使用label
    x, _ = iter(mnist_train).next()
    print('x:', x.shape)
 
    device = torch.device('cuda')
    #model = AE().to(device)
    model = VAE().to(device)
    criteon = nn.MSELoss()
    optimizer = optim.Adam(model.parameters(), lr=1e-3)
    print(model)
 
    viz = visdom.Visdom()
 
    for epoch in range(1000):
 
        for batchidx, (x, _) in enumerate(mnist_train):
            # [b, 1, 28, 28]
            x = x.to(device)
 
            x_hat, kld = model(x)
            loss = criteon(x_hat, x)
 
            if kld is not None:
                elbo = - loss - 1.0 * kld
                loss = - elbo
 
            # backprop
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
 
    print(epoch, 'loss', loss.item(), kld.item())
 
    x, _ = iter(mnist_test).next()
    x = x.to(device)
    with torch.no_grad(): 
 
 
    x_hat = model(x)
    # nrow表示一行的图片
    viz.images(x, nrow=8, win='x', optis=dic(title='x'))
    iz.images(x_hat, nrow=8, win='x_hat', optis=dic(title='x_hat'))
 
if __name__ == '__main__':
    main()

参考

讲解变分自编码器-VAE(附代码)
VAE到底在做什么?VAE原理讲解系列#1
VAE的神经网络是如何搭建的?VAE原理讲解系列#3
从零推导:变分自编码器(VAE)文章来源地址https://www.toymoban.com/news/detail-801258.html

到了这里,关于变分自编码器(Variational AutoEncoder,VAE)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 一分钟理解VAE(变分自编码器)

    VAE代表变分自编码器(Variational Autoencoder),是一种生成模型,它可以从输入数据中学习潜在变量,并生成新的样本。 VAE的输入和输出都是连续向量。输入通常是图像、文本或声音等数据类型,输出可以是相同类型的数据,也可以是新的数据样本。 Variational Autoencoder (VAE) 可以

    2024年02月15日
    浏览(39)
  • 变分自编码器(VAE)PyTorch Lightning 实现

    ✅作者简介:人工智能专业本科在读,喜欢计算机与编程,写博客记录自己的学习历程。 🍎个人主页:小嗷犬的个人主页 🍊个人网站:小嗷犬的技术小站 🥭个人信条:为天地立心,为生民立命,为往圣继绝学,为万世开太平。 变分自编码器 (Variational Autoencoder,VAE)是一

    2024年02月21日
    浏览(51)
  • 理解 Stable Diffusion、模型检查点(ckpt)和变分自编码器(VAE)

            在探索深度学习和人工智能领域的旅途中,理解Stable Diffusion、模型检查点(ckpt)以及变分自编码器(VAE)之间的关系至关重要。这些组件共同构成了当下一些最先进图像生成系统的基础。本文将为初学者提供一个详细的概述,帮助您理解这些概念以及它们是如何协同工作

    2024年01月21日
    浏览(45)
  • 简要介绍 | 生成模型的演进:从自编码器(AE)到变分自编码器(VAE)和生成对抗网络(GAN),再到扩散模型

    注1:本文系“简要介绍”系列之一,仅从概念上对生成模型(包括AE, VAE, GAN,以及扩散模型)进行非常简要的介绍,不适合用于深入和详细的了解。 生成模型在机器学习领域已经成为了一个热门的研究领域。它们的主要目标是学习数据的真实分布,以便能够生成新的、与真

    2024年02月14日
    浏览(52)
  • AI绘画——Stable Diffusion模型,变分自编码器(VAE)模型 , lora模型——调配设置与分享

    目录 Stable Diffusion模型 模型调配 模型设置  变分自编码器(VAE)模型  模型调配 模型设置   lora模型(原生)(插件) 模型调配 模型设置   AI生成prompt及模型分享 Stable Diffusion模型 pastel-mix+对应的VAE  Stable Diffusion模型国风+Lora模型 墨心+疏可走马 Stable Diffusion模型国风+Lo

    2024年02月04日
    浏览(59)
  • 变分自编码器生成新的手写数字图像

    变分自编码器(Variational Autoencoder,VAE) 是一种生成模型,通常用于学习数据的潜在表示,并用于生成新的数据样本。它由两部分组成:编码器和解码器。 编码器(Encoder) :接收输入数据,并将其映射到潜在空间中的分布。这意味着编码器将数据转换为均值和方差参数的分

    2024年04月11日
    浏览(44)
  • AIGC实战——使用变分自编码器生成面部图像

    在自编码器和变分自编码器上,我们都仅使用具有两个维度的潜空间。这有助于我们可视化自编码器和变分自编码器的内部工作原理,并理解自编码器和变分自编码潜空间分布的区别。在本节中,我们将使用更复杂的数据集,并了解增加潜空间的维度时,变

    2024年02月05日
    浏览(44)
  • AE(自动编码器)与VAE(变分自动编码器)的区别和联系?

    他们各自的概念看以下链接就可以了:https://blog.csdn.net/weixin_43135178/category_11543123.html  这里主要谈一下他们的区别? VAE是AE的升级版,VAE也可以被看作是一种特殊的AE AE主要用于数据的 压缩与还原 ,VAE主要用于 生成 。 AE是将数据映直接映射为数值 code(确定的数值) ,而

    2024年02月03日
    浏览(76)
  • 深度学习——自编码器AutoEncoder

    自编码器(Autoencoder)是一种无监督学习的神经网络模型,用于学习数据的低维表示。它由编码器(Encoder)和解码器(Decoder)两部分组成,通过将输入数据压缩到低维编码空间,再从编码空间中重构输入数据。 自编码器的基本结构如下: 1.编码器(Encoder):接收输入数据,

    2024年02月17日
    浏览(41)
  • AIGC实战——自编码器(Autoencoder)

    2024年02月05日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包