变分自编码器VAE代码

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

一,Auto-Encoder(AE)

        自编码器的目的是自己训练自己,他的输入和输出是一样的。比如28*28的黑白手写数字图片(单通道),如果使用矩阵形式进行表达,真正有作用的特征是哪些数值为1的地方,以及他们在矩阵空间的位置。而大部分边缘部分为0的地方对于特定任务来说都是冗余的特征。

        如果不使用CNN进行特征提取,常用的方法就是把矩阵平摊为一个784维度的向量,然后将这个向量实例化为一个Tensor,作为神经网络的输入。而AE的目的就是将这个784维度的向量压缩为一个低维的向量,这个低维度向量需要能够代表原始输入的那个784维度的输入。

        举个例子:手写数字图片为5的图片,平摊为784维度之后,通过AE进行降维,得到了一个20维度的向量,假设原始图片服从一个784维度的高斯分布,通过AE学习之后就变成了一个服从20维度的高斯分布。同样的,手写数字图片为6的图片也会被压缩成一个服从20维度的高斯分布。但是注意,图片5和图片6虽然都服从维度为20的高斯分布,但是他们的均值向量和方差向量肯定是存在显著差异的。注意:实际上AE的code编码向量分布是未知的,这里假设服从高斯分布。

变分自编码器VAE代码,Python数据分析,人工智能学习,python,机器学习,算法,人工智能

        AE的代码如下:

import numpy as np
import matplotlib.pyplot as plt
from keras.datasets import mnist
from keras.models import Model
from keras.layers import Input, Dense


# 加载MNIST数据集
(x_train, _), (x_test, _) = mnist.load_data()

# 设置潜在特征维度
latent_size =64

# 数据预处理
x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.
x_train = x_train.reshape((len(x_train), np.prod(x_train.shape[1:])))
x_test = x_test.reshape((len(x_test), np.prod(x_test.shape[1:])))

# 定义输入层
input_img = Input(shape=(784,))
# 定义编码层
encoded = Dense(latent_size =64, activation='relu')(input_img)
# 定义解码层
decoded = Dense(784, activation='sigmoid')(encoded)
# 构建自编码器模型
autoencoder = Model(input_img, decoded)
# 编译模型
autoencoder.compile(optimizer='adam', loss='mse') #mse尽可能使每一个像素与原来的接近

# 训练自编码器
autoencoder.fit(x_train, x_train,
                epochs=50,
                batch_size=256,
                shuffle=True,
                validation_data=(x_test, x_test))

# 构建编码器模型
encoder = Model(input_img, encoded)
# 构建解码器模型
encoded_input = Input(shape=(latent_size =64,))
decoder_layer = autoencoder.layers[-1]
decoder = Model(encoded_input, decoder_layer(encoded_input))
# 对测试集进行编码和解码
encoded_imgs = encoder.predict(x_test)
decoded_imgs = decoder.predict(encoded_imgs)

# 可视化结果
n = 10  # 可视化的图片数量
plt.figure(figsize=(20, 4))
for i in range(n):
    # 原始图片
    ax = plt.subplot(2, n, i + 1)
    plt.imshow(x_test[i].reshape(28, 28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)

    # 重构图片
    ax = plt.subplot(2, n, i + 1 + n)
    plt.imshow(decoded_imgs[i].reshape(28, 28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
plt.show()

二,变分自编码器VAE

        AE的目的就是将高维度的表示进行降维,实现用一个低维度的样本进行表示。而变分自编码器对AE进行了改进,VAE能够学习得到code编码进行波动之后产生的结果。从生成结果来说,VAE产生的结果与训练数据总是有那么一丝相似之处,而不会像AE可能会生成一个啥也不是的四不像图片(因为这个code在训练数据产生的code范围之外)。定性的说就是:AE只能根据固定的code产生结果,而VAE允许code产生误差。

        举个例子:如果潜在特征维度是一个10维度的向量,那么这个向量应该是服从一个10元正态高斯分布的,那么就会存在一个10维度的均值向量和一个10维度的标准差向量。VAE的做法就是:1,对于均值向量,使用神经网络直接训练出权重;2,对于标准差向量,令其尽量服从一个10维度的标准正态分布,从而训练得到标准差向量权重。然后使用重参数技巧进行采样,采样得到重构样本,然后计算损失函数。

        因此,VAE实际上是学习了一个分布函数,而这个概率分布函数只能通过神经网络学习,因为神经网络能够拟合出任意的非线性函数,而梯度下降又是一个完美的解决方法。

变分自编码器VAE代码,Python数据分析,人工智能学习,python,机器学习,算法,人工智能

        此外,由于VAE考虑到了分布的限制,因此他的损失函数有两部分:1,与AE一样的基于重构的误差,可以是MAE、MSE、BCE(可视为255类分类任务的准确性)等;2,基于分布相似度的损失,即KL散度,最大化潜在特征多元高斯分布与N元标准正态分布的相似度,有点类似于PINN(基于物理信息的神经网络),目的是减少反向传播时搜索的解空间,使训练过程收敛更快。上面的两部分损失都是一个似然的过程,即模型会尽量的满足训练数据,似训练数据的然,即解码器生成的图片99.999%都与训练数据里面有那么一丝丝相似。

变分自编码器VAE代码,Python数据分析,人工智能学习,python,机器学习,算法,人工智能

        VAE的难点是数学上准确的定量刻画两个分布之间的相似度以及从潜在特征向量进行采样时的可微性,即从离散采样变成连续表达的过程,且这个过程保持着相同的效果。可以这么认为,假如一个班级的身体平均值为170cm,我们采样时就以170cm为中心,以5*N(0,1)进行采样,得到的值就是165——175之间,而这个采样过程可以用N(170,0)+5*N(0,1)的正态分布进行代替。

变分自编码器VAE代码,Python数据分析,人工智能学习,python,机器学习,算法,人工智能

         总结VAE的思想就是:我们需要从观测值(也就是样本)去近似求得样本的分布函数P(x),遗憾的是这是很难实现的,但是我们可以把这个工作交给神经网络去实现。由GMM高斯混合模型,一个复杂分布可以通过任意个标准正态叠加得到。所以VAE就是以标准正态分布为基础,通过变换得到无限个正态分布,然后将这些变换得到的分布进行叠加去拟合原始数据的分布函数。而decoder的目的则是近似拟合得到了原始数据的近似分布P(x)。

变分自编码器VAE代码,Python数据分析,人工智能学习,python,机器学习,算法,人工智能

        上图中,u(x)、E(x)都是由神经网络进行代替的。VAE的代码如下。

# %%
import os
import tensorflow as tf
import numpy as np
import keras
from keras.layers import Dense,Input,concatenate,Lambda,add
from matplotlib import pyplot as plt
from keras.datasets import mnist
import keras.backend as K

# %%
# 加载MNIST数据集
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# 数据预处理
x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.
x_train = x_train.reshape((len(x_train), np.prod(x_train.shape[1:])))
x_test = x_test.reshape((len(x_test), np.prod(x_test.shape[1:])))

# %%
print(x_train.shape, y_train.shape)
print(x_test.shape, y_test.shape)

# %%
h_dim = 20
batchsz = 512
lr = 1e-3
z_dim = 10

# %%
class VAE(keras.Model):
    # 变分自编码器
    def __init__(self):
        super(VAE, self).__init__()
        # Encoder网络
        self.fc1 = Dense(128)
        self.fc2 = Dense(z_dim)  # get mean prediction
        self.fc3 = Dense(z_dim)

        # Decoder网络
        self.fc4 = Dense(128)
        self.fc5 = Dense(784)

    def encoder(self, x):
        # 获得编码器的均值和方差
        h = tf.nn.relu(self.fc1(x))
        # 获得均值向量
        mu = self.fc2(h)
        # 获得方差的log向量
        log_var = self.fc3(h)

        return mu, log_var

    def decoder(self, z):
        # 根据隐藏变量z生成图片数据
        out = tf.nn.relu(self.fc4(z))
        out = self.fc5(out)
        # 返回图片数据,784向量
        return out

    def reparameterize(self, mu, log_var):
        # reparameterize技巧,从正态分布采样epsilon
        eps = tf.random.normal(log_var.shape)
        # 计算标准差
        std = tf.exp(log_var*0.5)
        # reparameterize技巧
        z = mu + std * eps
        return z

    def call(self, inputs, training=None):
        # 前向计算
        # 编码器[b, 784] => [b, z_dim], [b, z_dim]
        mu, log_var = self.encoder(inputs)
        # 采样reparameterization trick
        z = self.reparameterize(mu, log_var)
        # 通过解码器生成
        x_hat = self.decoder(z)
        # 返回生成样本,及其均值与方差
        return x_hat, mu, log_var
    
# 创建网络对象
model = VAE()

# %%
model.build(input_shape=(4, 784))
# 优化器
optimizer = tf.optimizers.Adam(lr)

# %%
for epoch in range(10):  # 训练100个Epoch
    for step, x in enumerate(x_train):  # 遍历训练集
        # 打平,[b, 28, 28] => [b, 784]
        x = tf.reshape(x, [-1, 784])
        # 构建梯度记录器
        with tf.GradientTape() as tape:
            # 前向计算
            x_rec_logits, mu, log_var = model(x)
            # 重建损失值计算
            rec_loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=x, logits=x_rec_logits)
            rec_loss = tf.reduce_sum(rec_loss) / x.shape[0]

            kl_div = -0.5 * (log_var + 1 - mu**2 - tf.exp(log_var))
            kl_div = tf.reduce_sum(kl_div) / x.shape[0]
            # 合并误差项
            loss = rec_loss + 1. * kl_div
        # 自动求导
        grads = tape.gradient(loss, model.trainable_variables)
        # 自动更新
        optimizer.apply_gradients(zip(grads, model.trainable_variables))

        if step % 100 == 0:
            # 打印训练误差
            print(epoch, step, 'kl div:', float(kl_div), 'rec loss:', float(rec_loss))

# %%
# evaluation
# 测试生成效果,从正态分布随机采样z
z = tf.random.normal((batchsz, z_dim))
logits = model.decoder(z)  # 仅通过解码器生成图片
x_hat = tf.sigmoid(logits)  # 转换为像素范围
x_hat = tf.reshape(x_hat, [-1, 28, 28]).numpy() *255.
x_hat = x_hat.astype(np.uint8)


三,VAE的数学推导

        1,VAE假设code向量是服从正态分布的,解码器通过code向量生成图片,为了似然,会尽可能的使生成的图片与训练数据里面的类似。所以说decoder拟合的函数其实就是原始数据的近似分布。

变分自编码器VAE代码,Python数据分析,人工智能学习,python,机器学习,算法,人工智能

        2,如何得到P(z)呢?答案是利用神经网络直接进行训练。

变分自编码器VAE代码,Python数据分析,人工智能学习,python,机器学习,算法,人工智能

变分自编码器VAE代码,Python数据分析,人工智能学习,python,机器学习,算法,人工智能

        3,极大似然估计推导

变分自编码器VAE代码,Python数据分析,人工智能学习,python,机器学习,算法,人工智能

        4,由于KL散度恒等于0,可以化简得到其下边界。

变分自编码器VAE代码,Python数据分析,人工智能学习,python,机器学习,算法,人工智能

        5,下界可以通过条件概率进行改写。

变分自编码器VAE代码,Python数据分析,人工智能学习,python,机器学习,算法,人工智能

        6,继续拆分。可以得到P(z)必须服从正态分布才行,否则无法进行优化。而重构误差必须最小才能使网络达到收敛。

变分自编码器VAE代码,Python数据分析,人工智能学习,python,机器学习,算法,人工智能

参考:耿直哥,深度学习之自编码器(5)VAE图片生成实战_vae图像生成_炎武丶航的博客-CSDN博客文章来源地址https://www.toymoban.com/news/detail-610255.html

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

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

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

相关文章

  • 变分自编码器(VAE)PyTorch Lightning 实现

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

    2024年02月21日
    浏览(51)
  • AIGC实战——变分自编码器(Variational Autoencoder, VAE)

    我们已经学习了如何实现自编码器,并了解了自编码器无法在潜空间中的空白位置处生成逼真的图像,且空间分布并不均匀,为了解决这些问题#

    2024年02月05日
    浏览(38)
  • 理解 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)
  • 图像生成模型【自编码器、RNN、VAE、GAN、Diffusion、AIGC等】

    目录 监督学习 与 无监督学习 生成模型 自编码器 从线性维度压缩角度: 2D-1D 线性维度压缩: 3D-2D 推广线性维度压缩 流形 自编码器:流形数据的维度压缩 全图像空间 自然图像流形 自编码器的去噪效果 自编码器的问题 图像预测 (“结构化预测”) 显式密度模型 RNN PixelRNN [van

    2024年02月10日
    浏览(44)
  • 在 CelebA 数据集上训练的 PyTorch 中的基本变分自动编码器

    摩西·西珀博士         我最近发现自己需要一种方法将图像 编码到潜在嵌入中, 调整 嵌入,然后 生成 新图像。有一些强大的方法可以创建嵌入 或 从嵌入生成。如果你想同时做到这两点,一种自然且相当简单的方法是使用变分自动编码器。

    2024年02月05日
    浏览(55)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包