VAE原理详细直观化解析

VAE原理解析

Auto-Encoder

在这里插入图片描述
上图为普通的AutoEncoder,输入数据经过Encoder的编码,被压缩到一个称为“潜在空间”的较低维度表示中,这个潜在空间包含了模型学习到的数据的特征,我们将这个低维度表示抽象为潜在空间的某个点,然后Decoder会解析这个点去尽可能的去生成和原始数据接近的输出。但这样会有一个问题

输入数据x经过Encoder之后输出的是一个确定的潜在变量z,这个z代表着对数据的高度抽象的特征描述。例如途中的圆形、三角形、正方形,经过Encoder之后抽象为潜在空间中的三个点,Decoder通过解析这三个点生成和原始图形接近的输出,可是如果我们在这三个点之外随机取一个点(图中为紫色点),这个点经过Decoder的解析会生成一个没有意义的数据(例如图中紫色的线条),这个数据与原始输入数据之间没有任何关联。

也就是说在潜在空间中,除了这三个点是有意义的之外,其它的点没有任何意义。

这样的潜在空间是离散的,或者说是不平滑的。

VAE

那如果潜在空间变得平滑,也就是变得连续之后,有什么好处呢?

在这里插入图片描述

如图,在连续的潜在空间中,相似的输入数据对应的低维表示在这个空间中是接近的,也就是说潜在空间中每一个点都有意义,例如右图中红色的点既和三角形对应的点接近又离圆形对应的点接近,所以由这个红色的点生成的数据会是一个圆角的三角形。

也就是说当我们在这个平滑的潜在空间中改变数值时,生成的数据也会相应地变化,而且这种变化是渐进、连续的。这使得在潜在空间中的相近的点对应于相似的生成数据,同时也意味着我们可以在这个空间中执行插值,即在两个不同的数据点之间进行平滑的过渡,生成新的数据点,而这些新生成的数据点在原始数据中可能是合理的。

VAE是如何使潜在空间变得平滑的?

VAE实际上是通过引入概率的方式来使潜在空间变得平滑。

VAE的目标是学习数据真实的潜在表示,即p(z|x); 同时,将每个输入数据的潜在分布近似为一个标准正态分布(均值为0,方差为1)使潜在空间变得连续。

也就是说对于VAE来说,我们想要的不是一个确定的潜在表示 z z z,而是一个概率分布 p ( z ∣ x ) p(z|x) p(zx),这个概率分布表示在给定输入 x x x的条件下,潜在空间中潜在变量 z z z 的分布,这个概率分布被称为真实的后验概率分布,可是由于这个真实的后验概率分布难以计算,所以我们希望通过Encoder去生成一个近似的后验概率分布 q ( z ∣ x ) q(z|x) q(zx),我们希望这个生成的 q ( z ∣ x ) q(z|x) q(zx)去尽可能接近真实的概率分布 p ( z ∣ x ) p(z|x) p(zx),我们通过KL散度去衡量这两个概率分布之间的差值,我们希望这个差值尽可能地小。 q ( z ∣ x ) q(z|x) q(zx) p ( z ∣ x ) p(z|x) p(zx)的差距代表着模型学习数据潜在表示的能力即对输入数据特征抽取的能力。

ps: p ( z ∣ x ) p(z|x) p(zx)代表着输入数据真实的特征表示z的分布是什么样的,而我们设计各种各样的模型就是为了尽可能地计算或者接近这个特征表示的分布,从而更好地根据这个特征表示去重构数据。

通过让 q ( z ∣ x ) q(z|x) q(zx)近似于真实的后验分布 p ( z ∣ x ) p(z|x) p(zx),模型可以更好地捕捉数据的结构和特征,使得潜在空间中的点表示的输入数据的特征更加准确。这种潜在表示的学习有助于模型学习到数据的抽象表征,进而用于数据生成和重构。

KL Divergence(KL散度)

KL散度计算公式: D ( q ( z ∣ x ) ∣ ∣ p ( z ∣ x ) ) = E q ( z ∣ x ) [ l o g q ( z ∣ x ) p ( z ∣ x ) ] = E q ( z ∣ x ) [ l o g q ( z ∣ x ) − l o g p ( z ∣ x ) ] D(q(z|x) || p(z|x)) = E_{q(z|x)}[log \frac{q(z|x)}{p(z|x)}]= E_{q(z|x)}[log q(z|x) - log p(z|x)] D(q(zx)∣∣p(zx))=Eq(zx)[logp(zx)q(zx)]=Eq(zx)[logq(zx)logp(zx)] (1)

首先,我们通过以下公式转换KL公式:

l o g p ( z ∣ x ) = l o g p ( z , x ) p ( x ) log p(z|x)=log \frac{p(z,x)}{p(x)} logp(zx)=logp(x)p(z,x)

$D(q(z|x) || p(z|x)) = E_{q(z|x)}[log q(z|x) - log \frac{p(z,x)}{p(x)}] $

= E q ( z ∣ x ) [ l o g q ( z ∣ x ) − l o g p ( z , x ) ] + l o g p ( x ) = E_{q(z|x)}[log q(z|x) - log p(z,x)]+log p(x) =Eq(zx)[logq(zx)logp(z,x)]+logp(x)

也就是:
l o g p ( x ) = E q ( z ∣ x ) [ l o g p ( z , x ) − l o g q ( z ∣ x ) ] + D ( q ( z ∣ x ) ∣ ∣ p ( z ∣ x ) ) log p(x) = E_{q(z|x)}[log p(z,x) - log q(z|x)] + D(q(z|x) || p(z|x)) logp(x)=Eq(zx)[logp(z,x)logq(zx)]+D(q(zx)∣∣p(zx)) (2)

p ( x ) p(x) p(x) 可以被看作是在整个数据集上的概率密度函数,表示了在整个数据集中观察到任何数据点 x x x 的概率。这个 p ( x ) p(x) p(x)同样是难以计算的,但是,给定一个数据 x x x p ( x ) p(x) p(x) 是确定的,也就是说 p ( x ) p(x) p(x) 是一个定值

我们想让 D ( q ( z ∣ x ) ∣ ∣ p ( z ∣ x ) ) D(q(z|x) || p(z|x)) D(q(zx)∣∣p(zx))尽可能地小,也就是让第一项越来越大:

E L B O = E q ( z ∣ x ) [ l o g p ( z , x ) − l o g q ( z ∣ x ) ] ELBO = E_{q(z|x)}[log p(z,x) - log q(z|x)] ELBO=Eq(zx)[logp(z,x)logq(zx)] (3)

我们称之为Evidence lower bound(ELBO)。

同样的 l o g p ( z , x ) = l o g p ( z ) p ( x ∣ z ) = l o g p ( x ∣ z ) + l o g p ( z ) log p(z,x) = log p(z)p(x|z) = log p(x|z) + log p(z) logp(z,x)=logp(z)p(xz)=logp(xz)+logp(z)

代入ELBO可得:

E L B O = E q ( z ∣ x ) [ l o g p ( x ∣ z ) + l o g p ( z ) − l o g q ( z ∣ x ) ] ELBO =E_{q(z|x)}[log p(x|z) + log p(z)- log q(z|x)] ELBO=Eq(zx)[logp(xz)+logp(z)logq(zx)]

= E q ( z ∣ x ) [ l o g p ( x ∣ z ) ] − E q ( z ∣ x ) [ l o g q ( z ∣ x ) p ( z ) ] = E_{q(z|x)}[log p(x|z)] - E_{q(z|x)}[log \frac {q(z|x)}{p(z)}] =Eq(zx)[logp(xz)]Eq(zx)[logp(z)q(zx)]

我们发现第二项为q(z|x)和p(z)的KL散度,也就是说:

E L B O = E q ( z ∣ x ) [ l o g p ( x ∣ z ) ] − D ( q ( z ∣ x ) ∣ ∣ p ( z ) ) ELBO = E_{q(z|x)}[log p(x|z)] - D(q(z|x)||p(z)) ELBO=Eq(zx)[logp(xz)]D(q(zx)∣∣p(z)) (4)

要想最大化ELBO,就要最大化第一项,最小化第二项

第一项我们称为Reconstruction Likelihood(重构似然),它表示 p ( x ∣ z ) p(x|z) p(xz)的期望,表示给定潜在变量 z z z后,生成数据 x x x的概率。当我们从 q ( z ∣ x ) q(z|x) q(zx)中采样出 z z z,并通过解码器生成数据 x x x时,我们希望生成的 x x x能够尽可能地接近原始的 x x x,也就是说,我们希望 p ( x ∣ z ) p(x|z) p(xz)尽可能地大。也就是说==这一项也代表着输出数据与输入数据之间的损失。==

第二项为Regularization term(正则化项),这里指的是q(z|x)和p(z)的KL散度,也就是Encoder输出的分布和先验分布**p(z)**的相似度,我们最小化这一项就是希望让 q ( z ∣ x ) q(z|x) q(zx) p ( z ) p(z) p(z)尽可能地逼近。我们通常将 p ( z ) p(z) p(z)假定为一个单位高斯分布 N ( 0 , I ) N(0,I) N(0,I)即标准正态分布。通过这种正则化,VAE 被迫学习产生更加平滑和连续的潜在表示。

(ps:**标准正态分布是一个连续的、平滑的分布,通过鼓励潜在空间中的点遵循正态分布,VAE 能够推动相似的输入数据在潜在空间中彼此靠近,从而保持潜在空间的连续性和平滑性。**这意味着在潜在空间中邻近的点对应于输入空间中相似的数据点。)

在这里插入图片描述

By forcing the distributions to be close, we avoid “holes” in the latent space: we can move smoothly from one distribution to another without generating non-sense reconstructions.

在这里插入图片描述

==总结:==我们想让**近似的后验概率分布 q ( z ∣ x ) q(z|x) q(zx)去尽可能接近真实的概率分布 p ( z ∣ x ) p(z|x) p(zx),最终要做的就是 q ( z ∣ x ) q(z|x) q(zx)接近先验分布 p ( z ) p(z) p(z)(正则化),并且让模型最终的输出尽可能地接近原始的输入 x x x(重构似然)。**基于这个思想,我们稍微转换一下公式(4)便可以得到整个模型的损失函数:

L o s s = − E L B O Loss = -ELBO Loss=ELBO (具体的损失函数在实际的模型训练中会做出一些调整)

Reparameterization(重参数化)

重参数化(Reparameterization)是 Variational Autoencoder(VAE)中的一个关键技术。在 VAE 中,Encoder生成的潜在表示(latent representation)是一个概率分布,然后再从这个概率分布中进行随机采样,通过Decoder生成数据。这个随机采样操作本身是不可导的,也就不能进行反向传播(backpropagation)和梯度下降等优化方法来更新参数。

在这里插入图片描述
在这里插入图片描述

为了解决这个问题,重参数化技术被引入。它将随机采样操作从网络结构中分离出来,通过随机采样一个噪声分布,然后通过可导的操作将这个采样值转化为所需的潜在表示。这样就可以计算梯度并使用反向传播来训练整个网络。
在这里插入图片描述
在这里插入图片描述

具体来说,对于VAE模型,编码器网络会输出两个参数,一个表示均值( μ μ μ),另一个表示标准差( σ σ σ)。然后我们从标准正态分布中随机采样一个噪声值 ε ε ε。然后便可通过公式 z = μ + σ ∗ ε z = μ + σ * ε z=μ+σε 将采样操作转化为了一个可微的函数,这样也就使得从潜在分布中采样的过程成为可导的操作,允许梯度通过这个操作传播回编码器,进而进行模型参数的优化。

在这里插入图片描述

本篇笔记参考Autoencoders — Neurocomputing (julien-vitay.net)

Pytorch搭建一个简单的VAE模型

导包:

import torch
import torch.nn as nn
import torch.optim as optim

搭建模型:

class Encoder(nn.Module):
    def __init__(self, input_dim, hidden_dim, latent_dim):
        super(Encoder, self).__init__()
        self.fc1 = nn.Linear(input_dim, hidden_dim)
        self.fc2_mean = nn.Linear(hidden_dim, latent_dim)
        self.fc2_logvar = nn.Linear(hidden_dim, latent_dim)

    def forward(self, x):
        x = torch.relu(self.fc1(x))
        mean = self.fc2_mean(x)
        log_var = self.fc2_logvar(x)
        return mean, log_var

class Decoder(nn.Module):
    def __init__(self, latent_dim, hidden_dim, output_dim):
        super(Decoder, self).__init__()
        self.fc1 = nn.Linear(latent_dim, hidden_dim)
        self.fc2 = nn.Linear(hidden_dim, output_dim)

    def forward(self, z):
        z = torch.relu(self.fc1(z))
        reconstructed = torch.sigmoid(self.fc2(z))  # Adjust activation based on the data type
        return reconstructed

定义损失函数和优化器,训练模型:

# Initialize the models
encoder = Encoder(input_dim, hidden_dim, latent_dim)
decoder = Decoder(latent_dim, hidden_dim, output_dim)
model = VAE(encoder, decoder)

# Define the loss function
def loss_function(recon_x, x, mu, logvar):
    # Reconstruction loss
    recon_loss = nn.functional.binary_cross_entropy(recon_x, x, reduction='sum')
    # KL Divergence
    kl_divergence = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp())
    return recon_loss + kl_divergence

# Initialize the optimizer
optimizer = optim.Adam(model.parameters(), lr=learning_rate)

# Training loop
for epoch in range(num_epochs):
    model.train()
    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()
        optimizer.step()

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
分层VQ-VAE(Variational Autoencoder)是一种基变分自编码器的生成模型用于学习数据的潜在表示和多样的结构。其原理下: 1. 编码器(Encoder)分层VQ-VAE包含多编码器,每个编码器将数据映射到潜在表示空间。个编码器可以看作是一个逐编码的过程,其中较低层编码器学习表示的全局特征较高层的编码则学习表示数据的部特征。 2 潜在表示空间(Latent):潜在表示空间是编码生成的数据的低维表示。通过将输入数据映射到潜在表示空,模型可以捕捉数据中的关键特征,并实现对新样本的生成。 3. 器(Vector Quantizer):分层VQ-VAE使用量器将连的潜在表示离散为离散的代码本。这样做的好处是可以限制潜在表示的维度,并增加模型的稳定性。量器将潜在表示映射到最接近的离散代码本中的向量。 4. 解码器(Decoder):解码器将离散的代码本向量映射回原始数据空间,从而实现对新样本的生成。解码器的目标是最大程度地重构输入数据,使得生成的样本与真实数据尽可能接近。 5. 损失函数(Loss Function):分层VQ-VAE使用重构损失和潜在表示损失作为训练过程中的目标函数。重构损失衡量了生成样本与真实数据之间的差异,潜在表示损失则衡量了离散代码本向量与潜在表示之间的差异。 通过编码器、量器和解码器的组合,分层VQ-VAE可以学习数据的潜在表示并生成多样的结构。该模型可以应用于多个领域,如图像生成、音频合成和异常检测等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值