Variational Autoencoder 变分自动编码器

本文逐步介绍了如何构建一个变分自编码器(VAE),从最简单的全连接层开始,逐渐深入到使用多层全链接层和深度卷积网络。通过CIFAR10数据集展示了VAE的训练过程,并详细解析了VAE的损失函数,特别是变分推断中的KL散度和重构造误差。最后,解释了重参数化技巧在解决采样不可导问题中的关键作用。

一步一步实现一个VAE

大部分来自Keras VAE的教程,不过没有使用mnist,而是用了cifar10的数据集

最简单的两个全链接层的Autoencoder

先贴个代码:

# this is the size of our encoded representations
encoding_dim = 32  # 32 floats -> compression of factor 24.5, assuming the input is 784 floats
# this is our input placeholder
input_img = Input(shape=(784,))
# "encoded" is the encoded representation of the input
encoded = Dense(encoding_dim, activation='relu')(input_img)
# "decoded" is the lossy reconstruction of the input
decoded = Dense(784, activation='sigmoid')(encoded)
# this model maps an input to its reconstruction
autoencoder = Model(input_img, decoded)
# this model maps an input to its encoded representation
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')

这里就是把输入层放入一个全链接层,压缩成为一个32维的数组,然后再使用这个32维的数组用一个全链接层去还原原来的图片。
下面这段代码是用来显示效果,这里还是用的mnist的数据集。

encoder = Model(input_img, encoded)
# create a placeholder for an encoded (32-dimensional) input
encoded_input = Input(shape=(encoding_dim,))
# retrieve the last layer of the autoencoder model
decoder_layer = autoencoder.layers[-1]
# create the decoder model
decoder = Model(encoded_input, decoder_layer(encoded_input))

结果如下:
两个全链接层autoencoder的效果

使用多层全链接层的Autoencoder

input_img = Input(shape=(784,))
encoded = Dense(128, activation='relu')(input_img)
encoded = Dense(64, activation='relu')(encoded)
encoded = Dense(32, activation='relu')(encoded)

decoded = Dense(
### 变分自动编码器VAE)的概念与原理 变分自动编码器Variational Autoencoder, VAE)是一种基于深度学习的生成模型,它结合了自动编码器的思想和概率论中的变分推断技术。其核心目标是从潜在空间中采样并生成新的数据样本。 #### 自动编码器的基础 自动编码器是一种无监督学习模型,主要由两部分组成:编码器和解码器[^1]。 - **编码器**的作用是将高维输入数据压缩为低维表示(即隐空间向量 \(z\))。 - **解码器**的任务则是从这个低维表示重建原始输入数据。 通过最小化重构误差(通常采用均方误差),自动编码器能够学习到输入数据的有效特征表达[^3]。 然而,传统的自动编码器并不适合生成新数据,因为它们无法保证隐空间具有良好的连续性和可解释性。这正是引入变分自动编码器的原因之一。 --- #### VAE 的工作原理 VAE 是一种改进版的自动编码器,旨在解决传统自动编码器在生成能力上的不足。它的设计思路如下: 1. **隐空间的概率建模** 在 VAE 中,编码器不仅输出一个固定的隐向量 \(z\),还输出两个参数:均值向量 \(\mu\) 和标准差向量 \(\sigma\)。这两个参数定义了一个多元正态分布 \(q_\phi(z|x)\),其中 \(x\) 表示输入数据,\(\phi\) 表示编码器的参数[^2]。 2. **重参数化技巧** 为了使得梯度可以通过反向传播传递至编码器,VAE 使用了一种称为“重参数化”的方法。具体来说,\(z\) 被重新定义为: \[ z = \mu + \epsilon \cdot \sigma,\quad \text{where } \epsilon \sim N(0, I) \] 这一操作允许优化算法直接作用于 \(\mu\) 和 \(\sigma\) 上,从而实现端到端的学习[^4]。 3. **损失函数的设计** VAE 的总损失函数由两部分组成: - **重构误差**:衡量解码器生成的数据与真实数据之间的差异,常用交叉熵或均方误差表示。 - **KL 散度项**:约束隐空间分布接近标准正态分布 \(N(0, I)\),以确保隐空间具备平滑性和可生成性。最终的目标是最小化以下形式的 ELBO(Evidence Lower Bound): \[ L_{ELBO} = D_{KL}(q_\phi(z|x)||p(z)) - E_q[\log p(x|z)] \] --- #### VAE 的实现方法 以下是使用 Python 和 PyTorch 实现的一个简单 VAE 示例: ```python import torch import torch.nn as nn import torch.optim as optim class VAE(nn.Module): def __init__(self, input_dim=784, latent_dim=20): super(VAE, self).__init__() # 编码器层 self.encoder_fc = nn.Linear(input_dim, 512) self.mu_layer = nn.Linear(512, latent_dim) self.logvar_layer = nn.Linear(512, latent_dim) # 解码器层 self.decoder_fc = nn.Linear(latent_dim, 512) self.output_layer = nn.Linear(512, input_dim) def encode(self, x): h = torch.relu(self.encoder_fc(x)) mu = self.mu_layer(h) log_var = self.logvar_layer(h) return mu, log_var def reparameterize(self, mu, log_var): std = torch.exp(0.5 * log_var) eps = torch.randn_like(std) return mu + eps * std def decode(self, z): h = torch.relu(self.decoder_fc(z)) return torch.sigmoid(self.output_layer(h)) def forward(self, x): mu, log_var = self.encode(x.view(-1, 784)) z = self.reparameterize(mu, log_var) recon_x = self.decode(z) return recon_x, mu, log_var # 定义损失函数 def vae_loss(recon_x, x, mu, log_var): reconstruction_loss = nn.BCELoss()(recon_x, x.view(-1, 784)) kl_divergence = -0.5 * torch.sum(1 + log_var - mu.pow(2) - log_var.exp()) return reconstruction_loss + kl_divergence / (batch_size * 784) model = VAE() optimizer = optim.Adam(model.parameters(), lr=1e-3) ``` 此代码展示了如何构建一个简单的 VAE 模型,并定义相应的损失函数。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值