变分自编码器VAE

基于变分的自编码器(variational Autoencoder)是2014由Kingma等人提出的一种基于变分贝叶斯推断的生成网络。与传统的生成网络相比它具有两点优势:
1。避免了复杂的边界似然概率(太难了,谁会算啊)
2。避免了马尔科夫链的采样过程(好像最近很火生成对抗网络也避免了这个)

1. 生成器网络

对于一堆我们收集到的样本,这些样本在默认情况下来自一个独立的同分布,也就是我们常说的iid。我们不妨把这个概率分布记作p(x),然而想搞清楚这个概率分布是很难的,因为我们要对这个概率的边缘分布进行积分。于是乎,就有高人想到了能不能用一个简单的概率分布去近似我们未知的复杂概率,于是乎就有人将这个概率命名为q(x)。有了这两个概率以后,需要建立一种度量方式来比较两个概率分布的相似程度,因此给出出这两个概率分布的潜变量的产生概率的KL散度
KL(p||q)=plogpq

2. 边分边界

当我有了两个概率分布的评价模型以后,需要做的就是优化。首先将KL散度进行拆分:
p(z|x)logp(z|x)q(z|x)=p(z|x)logp(z|x)p(z|x)logq(z|x)
根据贝叶斯公式,p(z|x)=px|z)p(z)p(x)
KL=p(z|x)[logq(z|x)logp(x,z)]+logp(x)
其中,中间含有的一项可以看做是相关分布在概率分布p(z|x)下的期望。我们可以将这一项记为L重写一下式子,通过变形可以得到:
logp(x)=KL+L 其中L就是这个Kl分布
假设我们的概率优化的够好,让我们的变分下界尽可能的大,那么我们的KL散度就会越来越小,两个概率分布的相似性就会越来越好。
logp(x)L=Eq(z|x)[logq(z|x)+logp(x,z)]通过一系列变换,结合贝叶斯,可以得到L=KL(q(z|x)||p(z))+Eq(z|x)[logp(x|z)]

3. 变分自编码器

上面的式子可以简写成Eq(z|x)[f(z)],也就是将原分布看做一个关于z的函数,记为z=g(ϵ,x),在x是已知的情况下,我们的整个z的产生将由ϵ决定。
针对自编码器的结构,我们采用多维标准高斯进行逼急z的后验分布q(z|x)
结合keras中的vae代码进行分析:

@author: sky
"""

'''This script demonstrates how to build a variational autoencoder with Keras.
Reference: "Auto-Encoding Variational Bayes" https://arxiv.org/abs/1312.6114
'''
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm

from keras.layers import Input, Dense, Lambda
from keras.models import Model
from keras import backend as K
from keras import objectives
from keras.datasets import mnist

batch_size = 100
original_dim = 784
latent_dim = 2
intermediate_dim = 256
nb_epoch = 50
epsilon_std = 1.0
#定义模型初始化
x = Input(batch_shape=(batch_size, original_dim))
h = Dense(intermediate_dim, activation='relu')(x)
z_mean = Dense(latent_dim)(h)
z_log_var = Dense(latent_dim)(h)
#建立一个连接模型,这里的z_mean代表了高斯分布的均值,z_log_var代表了高斯分布方差的对数表达。

def sampling(args):
    z_mean, z_log_var = args
    epsilon = K.random_normal(shape=(batch_size, latent_dim), mean=0.,
                              std=epsilon_std)
    return z_mean + K.exp(z_log_var / 2) * epsilon
#建立一个采样方程,最终返回一个生成的z
# note that "output_shape" isn't necessary with the TensorFlow backend
z = Lambda(sampling, output_shape=(latent_dim,))([z_mean, z_log_var])


decoder_h = Dense(intermediate_dim, activation='relu')
decoder_mean = Dense(original_dim, activation='sigmoid')
h_decoded = decoder_h(z)
#将采样后的z映射到隐含层中(可以参考AE)
x_decoded_mean = decoder_mean(h_decoded)
#对隐含层的h进行解码得到重构样本x

def vae_loss(x, x_decoded_mean):
    xent_loss = original_dim * objectives.binary_crossentropy(x, x_decoded_mean)
    kl_loss = - 0.5 * K.sum(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1)
    return xent_loss + kl_loss
#定义整个模型的损失函数,包括了让采样尽可能的靠近标准高斯分布和隐含层的解码值与原始样本更加接近。
vae = Model(x, x_decoded_mean)
vae.compile(optimizer='rmsprop', loss=vae_loss)

# train the VAE on MNIST digits
(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:])))

vae.fit(x_train, x_train,
        shuffle=True,
        nb_epoch=nb_epoch,
        batch_size=batch_size,
        validation_data=(x_test, x_test))

这样就可以实现VAE的训练

### 变分自编码器 (VAE) 的原理 变分自编码器(VAE, Variational Autoencoder) 是一种深度学习模型,旨在用于数据生成和特征学习。这种模型结合了自编码器(autoencoders) 和贝叶斯推断的方法[^1]。 在传统自编码器的基础上,VAE 引入了概率论和信息论中的概念来建模输入数据的分布情况。具体来说,在编码阶段,给定一个输入 \( \mathbf{x} \),通过神经网络映射到隐空间的一个参数化高斯分布上;而在解码阶段,则是从该分布中采样得到具体的隐藏向量并重建原始输入\[ ^{2}\]. 为了确保所学得的潜在表示具有良好的性质(比如平滑性和连续性),VAE 加入了一个正则项即KL散度损失,使得学到的概率分布在形式上接近标准正态分布\( N(0,I)\)[^2]. 这种设计不仅有助于提高泛化能力而且可以用来生成新样本. ### VAE 的实现方法 以下是基于 PyTorch 构建简单版本 VAE 的代码片段: ```python import torch.nn as nn from torch import optim class Encoder(nn.Module): def __init__(self, input_dim, hidden_dim, latent_dim): super().__init__() self.fc1 = nn.Linear(input_dim, hidden_dim) self.fc_mu = nn.Linear(hidden_dim, latent_dim) self.fc_logvar = nn.Linear(hidden_dim, latent_dim) def forward(self, x): h = F.relu(self.fc1(x)) mu = self.fc_mu(h) log_var = self.fc_logvar(h) return mu, log_var class Decoder(nn.Module): def __init__(self, latent_dim, hidden_dim, output_dim): super().__init__() self.fc1 = nn.Linear(latent_dim, hidden_dim) self.fc_out = nn.Linear(hidden_dim, output_dim) def forward(self, z): h = F.relu(self.fc1(z)) recon_x = torch.sigmoid(self.fc_out(h)) return recon_x def reparameterize(mu, log_var): std = torch.exp(log_var / 2.) eps = torch.randn_like(std) return mu + eps * std # 定义整个VaeModel类... ``` 这段代码展示了如何定义编码器、解码器以及重参技巧(reparameterization trick), 并利用它们共同组成完整的 VAE 模型框架[^3]. ### 应用场景 由于其独特的能力,VAE 已经被应用于多个领域: - **图像生成**: 利用 VAE 学习图片集上的低维表达,并据此合成逼真的新型图像. - **降维与可视化**: 类似于 PCA 或 t-SNE 技术,但能捕捉更复杂的非线性关系. - **异常检测**: 对正常模式下的观测建立模型,当遇到偏离此模式的新实例时发出警报. - **缺失值填补**: 使用已知部分预测未知区域的数据填充策略.[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值