VAE的原理和代码实现

VAE的原理和代码实现


极力推荐:
http://www.gwylab.com/note-vae.html
重要参考:
https://spaces.ac.cn/archives/5253
https://www.jianshu.com/p/ff28eef92fa1
完整代码:
https://github.com/taichuai/d2l_zh_tensorflow2.0/blob/master/VAE%E5%AE%9E%E6%88%98.ipynb


VAE(Variational Autoencoder)中文译为变分自动编码器,它是一种深度生成模型(Deep Generative Model),是一种无监督学习算法。那么VAE的设计思路来源是什么?VAE能干嘛?代码如何实现?以及还可以怎样改进呢?下面一一道来。

1、VAE的设计来源
在这里插入图片描述
2、VAE的主要思路
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、VAE究竟能干嘛

可以用来生成接近训练数据的不同数据,包括图像生成,音频合成等。

4、VAE的tf2代码实现

简单来讲,重点在于类似两个encoder编码(都写在encoder中),生成均值方差,然后使用重参数采样reparameterize计算得到隐向量

z_dim = 10


from tensorflow.keras import Sequential

class VAE(keras.Model):
    def __init__(self):
        super(VAE, self).__init__()
        # encoder
        self.e1 = keras.layers.Dense(128)
        print(self.e1)
        self.e2 = keras.layers.Dense(z_dim)   # get mean prediction
        self.e3 = keras.layers.Dense(z_dim)   #  get mean prediction
        
        # decoder
        self.fc4 = keras.layers.Dense(128)
        self.fc5 = keras.layers.Dense(784)
    
    def encoder(self, inputs):
        h = self.e1(inputs)
        h = tf.nn.relu(h)
        # get_mean
        mean = self.e2(h)
        # get_variance
        log_var = self.e3(h)    # 一般方差做一个log,方便计算
        
        return mean, log_var
    
    def decoder(self, z):
        out = tf.nn.relu(self.fc4(z))
        out = self.fc5(out)
        
        return out
    
    def reparameterize(self, mean, log_var):
        eps = tf.random.normal(tf.shape(log_var))
        
        std = tf.exp(log_var)**0.5    # 开根号
        
        z = mean + std * eps
        
        return z
        
    
    def call(self, inputs, training=None):
        # [b, 784] -> [b, z_dim], [b, z_dim]
        mean, log_var = self.encoder(inputs)
        # trick: reparameterization trick,采样
        z = self.reparameterize(mean, log_var)
        x_hat = self.decoder(z)
        
        # 返回 x 的同时,返回 mean和val作为约束
        return x_hat, mean, log_var

5、VAE改进??

在这里插入图片描述
关于cvae的实现代码可参考苏神,其实就是修改 KL_loss损失,:

# 只需要修改K.square(z_mean)为K.square(z_mean - yh),也就是让隐变量向类内均值看齐
kl_loss = - 0.5 * K.sum(1 + z_log_var - K.square(z_mean - yh) - K.exp(z_log_var), axis=-1)

具体的
https://github.com/bojone/vae/blob/master/cvae_keras.py

  • 13
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个使用PyTorch实现Variational Autoencoder (VAE)的简单代码示例: ```python import torch import torch.nn as nn import torch.optim as optim import torch.nn.functional as F from torchvision import datasets, transforms # 定义VAE模型 class VAE(nn.Module): def __init__(self): super(VAE, self).__init__() self.fc1 = nn.Linear(784, 400) self.fc21 = nn.Linear(400, 20) # 均值 self.fc22 = nn.Linear(400, 20) # 方差 self.fc3 = nn.Linear(20, 400) self.fc4 = nn.Linear(400, 784) def encode(self, x): h1 = F.relu(self.fc1(x)) return self.fc21(h1), self.fc22(h1) def reparameterize(self, mu, logvar): std = torch.exp(0.5 * logvar) eps = torch.randn_like(std) return mu + eps * std def decode(self, z): h3 = F.relu(self.fc3(z)) return torch.sigmoid(self.fc4(h3)) def forward(self, x): mu, logvar = self.encode(x.view(-1, 784)) z = self.reparameterize(mu, logvar) return self.decode(z), mu, logvar # 计算VAE的损失函数 def loss_function(recon_x, x, mu, logvar): BCE = F.binary_cross_entropy(recon_x, x.view(-1, 784), reduction='sum') KLD = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp()) return BCE + KLD # 加载MNIST数据集 train_loader = torch.utils.data.DataLoader( datasets.MNIST('../data', train=True, download=True, transform=transforms.ToTensor()), batch_size=128, shuffle=True) # 初始化VAE模型和优化器 model = VAE() optimizer = optim.Adam(model.parameters(), lr=1e-3) # 训练VAE模型 def train(epoch): model.train() train_loss = 0 for batch_idx, (data, _) in enumerate(train_loader): optimizer.zero_grad() recon_batch, mu, logvar = model(data) loss = loss_function(recon_batch, data, mu, logvar) loss.backward() train_loss += loss.item() optimizer.step() if batch_idx % 100 == 0: print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format( epoch, batch_idx * len(data), len(train_loader.dataset), 100. * batch_idx / len(train_loader), loss.item() / len(data))) print('====> Epoch: {} Average loss: {:.4f}'.format( epoch, train_loss / len(train_loader.dataset))) # 使用训练好的VAE生成一些样本 def generate_samples(num_samples): with torch.no_grad(): sample = torch.randn(num_samples, 20) sample = model.decode(sample).cpu() return sample # 开始训练和生成样本 num_epochs = 10 for epoch in range(1, num_epochs + 1): train(epoch) samples = generate_samples(10) ``` 这个代码示例实现了一个简单的VAE模型,使用MNIST数据集进行训练和生成样本。你可以根据实际情况进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值