VAE 总结整理

VAE 总结整理

原始VAE介绍

VAE是一种生成模型,通过隐变量z生成目标数据X。核心是希望训练一种模型,可以将某个概率分布映射到训练集的概率分布。

所以核心在于:

1)隐变量的概率分布如何选择

2)如何衡量生成的概率分布与已有的概率分布之间的差异

3)如何将这种差异用于调整网络参数

变量列表

变量名 含义
X , X X, \mathcal X X,X 数据点,数据点所属空间
D a t e Date Date 数据集, X X X是从 D a t a Data Data中采样得到的
P ( ∗ ) P(*) P() 变量 ∗ * 的概率
p ( ∗ ) p(*) p() 变量 ∗ * 的概率密度函数
z , Z z,\mathcal Z z,Z 隐变量,隐变量所属空间
f ( ∗ ) f(*) f() 神经网络
q ( z ) q(z) q(z) 更容易产生X的z空间对应的概率密度函数
θ , Θ \theta,\mathcal \Theta θ,Θ 网络参数,参数空间
μ \mu μ 均值
σ \sigma σ 标准差
ϵ \epsilon ϵ 参数重整化技巧用到的变量, ϵ ∼ N ( 0 , I ) \epsilon \sim \mathcal N(0,I) ϵN(0,I)
D \mathcal D D KL散度

网络思想

在生成模型中,需要一个隐变量指导网络生成对象。比如,在生成0~9的手写字符时,先决定生成哪一个数字,再进行生成,也就是有一个映射 f : Z × Θ → X f:\mathcal Z × \mathcal \Theta \rightarrow \mathcal X f:Z×ΘX。如果在 Z \mathcal Z Z上随机采样,随机变量是 z z z,概率密度函数是 p ( z ) p(z) p(z),根据全概率公式:
p ( X ) = ∫ p ( X ∣ z ; θ ) p ( z ) d z p(X)=\int p(X|z;\theta)p(z)dz p(X)=p(Xz;θ)p(z)dz
也就是希望生成 X X X的概率最大。在VAE中,一般假定输出满足正态分布,即 X = f ( z ; θ ) ∼ N ( f ( z ; θ ) , σ 2 I ) X=f(z;\theta) \sim \mathcal N(f(z;\theta),\sigma^2I) X=f(z;θ)N(f(z;θ),σ2I)

编码器

为了求解(1)中的积分,需要处理两个问题:如何定义 z z z,如何在 z z z上积分。

问题1:如何定义z

假定 z z z并不能直接解释,但是可以从一个简单的分布中提取,比如正态分布 N ( 0 , I ) \mathcal N(0,I) N(0,I),因为只要有一个足够复杂的映射,比如神经网络 f ( z ; θ ) f(z;\theta) f(z;θ),d维的正态分布可以变为d维中的任意分布。

问题2:如何求解积分(1)

首先从因空间中提取足够多的 z = { z 1 , z 2 , . . . z n } z=\{z_1,z_2,...z_n\} z={ z1,z2,...zn},再计算 p ( X ) ≈ 1 n ∑ i = 1 n p ( X ∣ z i ) p(X) \approx \frac {1}{n}\sum\limits_{i=1}^{n}p(X|z_i) p(X)n1i=1np(Xzi)

但是这带来了新的问题:

1)为了成功估计p(x)​,n值要取很大,很多的z对于X的生成不起作用;

2)由于假定X满足高斯分布,其实也就是 A e x p { − ∣ ∣ X − f ( z ; θ ) ∣ ∣ 2 2 σ 2 } Aexp\{-\frac {||X-f(z;\theta)||^2}{2\sigma^2}\} Aexp{ 2σ2Xf(z;θ)2},核心是一个平方距离 ∣ ∣ X − f ( z ; θ ) ∣ ∣ 2 ||X-f(z;\theta)||^2 Xf(z;θ)2,也就导致不那么像X的生成结果反而得分比较高:

在这里插入图片描述

为了避免以上的问题,VAE将重心放在对X生成贡献大的z上。

采用一个新的分布 q ( z ∣ X ) ∈ Q q(z|X)∈Q q(zX)Q,显然 Q ⫋ Z Q\subsetneqq\mathcal Z QZ,计算 E z ∼ Q p ( X ∣ z ) E_{z\sim Q}p(X|z) EzQp(Xz)就很容易, q q q不是标准正态分布。首先将 E z ∼ Q p ( X ∣ z ) E_{z\sim Q}p(X|z) EzQp(Xz) p ( X ) p(X) p(X)联系起来。从KL散度入手:
KaTeX parse error: No such environment: align at position 8: \begin{̲a̲l̲i̲g̲n̲}̲ \mathcal D[q(z…
移项,得
KaTeX parse error: No such environment: align at position 8: \begin{̲a̲l̲i̲g̲n̲}̲ logp(X)-\mathc…
观察这个等式,左边是我们的优化目标:

1) l o g p ( X ) logp(X) logp(X)要尽可能大,越大说明我们从z生成X的效果越好;

2) D [ q ( z ) ∣ ∣ p ( z ∣ X ) ] \mathcal D[q(z)||p(z|X)] D[q(z)p(zX)]要尽可能小,越小说明 q q q p p p越接近,也就是说明我们 Q Q Q空间接近可以产生X的 Z \mathcal Z Z空间部分;

3) p ( X ∣ z ) ] p(X|z)] p(Xz)]充当了解码器,将z映射到X;

4) q ( z ∣ X ) q(z|X) q(zX)充当了编码器,将X映射到z;

损失函数
第一项: l o g p ( X ∣ z ) logp(X|z) logp(Xz)

由于我们假设 X = f ( z ; θ ) ∼ N ( f ( z ; θ ) , σ 2 I ) X=f(z;\theta) \sim \mathcal N(f(z;\theta),\sigma^2I) X=f(z;θ)N(f(z;θ),σ2I),所以取了对数以后,直接看分子的平方项即可,其余都是常数。那么也就是 E z ∼ Q [ 1 n σ 2 ∣ ∣ X − f ( z ; θ ) ∣ ∣ 2 ] E_{z\sim Q}[\frac{1}{n\sigma^2}||X-f(z;\theta)||^2] EzQ[nσ21Xf(z;θ)2]

第二项: D [ q ( z ∣ X ) ∣ ∣ p ( z ) ] \mathcal D[q(z|X)||p(z)] D[q(zX)p(z)]

假设 q ( z ∣ X ) = N ( μ ( X ) , Σ ( X ) ) q(z|X)= \mathcal N(\mu(X),\Sigma(X)) q(zX)=N(μ(X),Σ(X)),那么计算两个正态分布的KL散度即可。

首先看一般的:
D [ N ( μ 0 , Σ 0 ) ∣ ∣ N ( μ 1 , Σ 1 ) ] = E X ∼ N 0 [ l o g N 0 − l o g N 1 ] = 1 2 E X ∼ N 0 [ − l o g ∣ Σ 0 ∣ + l o g ∣ Σ 1 ∣ − ( X − μ 0 ) T Σ 0 − 1 ( X − μ 0 ) + ( X − μ 1 ) T Σ 1 − 1 ( X − μ 1 ) ] = 1 2 l o g ∣ Σ 1 ∣ ∣ Σ 0 ∣ − 1 2 E X ∼ N 0 [ ( X − μ 0 ) T Σ 0 − 1 ( X − μ 0 ) + ( X − μ 0 − μ 1 + μ 0 ) T Σ 1 − 1 ( X − μ 0 − μ 1 + μ 0 ) ]

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
VAE是一种生成模型,用于学习输入数据的潜在分布,并从中生成新的样本。它由一个编码器网络和一个解码器网络组成。编码器将输入图像映射为潜在空间中的两个向量,即均值向量z_mean和对数方差向量z_log_var。解码器则将潜在向量z解码为重建图像。 在Python中实现VAE的伪代码如下: ```python # VAE编码器网络 from tensorflow import keras from tensorflow.keras import layers from tensorflow.keras import backend as K from tensorflow.keras.models import Model img_shape = (28, 28, 1) batch_size = 16 latent_dim = 2 input_img = keras.Input(shape=img_shape) x = layers.Conv2D(32, 3, padding='same', activation='relu')(input_img) x = layers.Conv2D(64, 3, padding='same', activation='relu', strides=(2, 2))(x) x = layers.Conv2D(64, 3, padding='same', activation='relu')(x) = layers.Conv2D(64, 3, padding='same', activation='relu')(x) shape_before_flattening = K.int_shape(x) x = layers.Flatten()(x) x = layers.Dense(32, activation='relu')(x) z_mean = layers.Dense(latent_dim)(x) z_log_var = layers.Dense(latent_dim)(x) # VAE解码器网络 z = layers.Input(shape=(latent_dim,)) x = layers.Dense(np.prod(shape_before_flattening[1:]), activation='relu')(z) x = layers.Reshape(shape_before_flattening[1:])(x) x = layers.Conv2DTranspose(32, 3, padding='same', activation='relu', strides=(2, 2))(x) x = layers.Conv2D(1, 3, padding='same', activation='sigmoid')(x) reconstructed_img = x # 构建VAE模型 encoder = Model(input_img, z_mean, z_log_var) decoder = Model(z, reconstructed_img) vae_output = decoder(encoder(input_img)) vae = Model(input_img, vae_output) # 定义损失函数和训练过程 def vae_loss(input_img, vae_output): reconstruction_loss = keras.losses.binary_crossentropy(input_img, vae_output) reconstruction_loss *= img_shape[0] * img_shape[1] kl_loss = 1 + z_log_var - K.square(z_mean) - K.exp(z_log_var) kl_loss = K.sum(kl_loss, axis=-1) kl_loss *= -0.5 vae_loss = K.mean(reconstruction_loss + kl_loss) return vae_loss vae.compile(optimizer='adam', loss=vae_loss) vae.fit(train_images, train_images, batch_size=batch_size, epochs=epochs) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值