代码是理解Vae和标准自动编码器的正确方法吗?

2024-10-03 23:18:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经为标准自动编码器和VAE创建了两个迷你编码网络,并分别绘制了它们。我只想知道我对这个小案子的理解是否正确。注意,它只有一个历元,以编码结束

import numpy as np
from matplotlib import pyplot as plt

np.random.seed(0)

fig, (ax,ax2) = plt.subplots(2,1)

def relu(x):
    c = np.where(x>0,x,0)
    return c


#Standard autoencoder
x = np.random.randint(0,2,[100,5])
w_autoencoder = np.random.normal(0,1,[5,2])


bottle_neck = relu(x.dot(w_autoencoder))

ax.scatter(bottle_neck[:,0],bottle_neck[:,1])

#VAE autoencoder

w_vae1 = np.random.normal(0,1,[5,2])
w_vae2 = np.random.normal(0,1,[5,2])

mu = relu(x.dot(w_vae1))
sigma = relu(x.dot(w_vae2))

epsilon_sample = np.random.normal(0,1,[100,2])

latent_space = mu+np.log2(sigma)*epsilon_sample

ax2.scatter(latent_space[:,0], latent_space[:,1],c='red')

w_vae1 = np.random.normal(0,1,[5,2])
w_vae2 = np.random.normal(0,1,[5,2])

mu = relu(x.dot(w_vae1))
sigma = relu(x.dot(w_vae2))

epsilon_sample = np.random.normal(0,1,[100,2])

latent_space = mu+np.log2(sigma)*epsilon_sample

ax2.scatter(latent_space[:,0], latent_space[:,1],c='red')


Tags: samplenpspacerandomsigmadotrelunormal
1条回答
网友
1楼 · 发布于 2024-10-03 23:18:12

既然你的动机是“理解”,我应该说你是在正确的方向上工作,在这种执行肯定有助于你理解。但我坚信“理解”必须首先在书籍/论文中实现,然后才能通过实现/代码实现

快速浏览一下,您的标准自动编码器看起来不错。您正在通过实现进行一个假设,即使用relu(x),您的潜在代码将在(0,无穷大)范围内

但是,在执行VAE时,您无法使用relu(x)函数实现潜在代码。这就是你“理论”理解缺失的地方。在标准VAE中,我们假设潜码是高斯分布的样本,因此我们近似该高斯分布的参数,即均值和协方差。此外,我们还假设这个高斯分布是阶乘的,这意味着协方差矩阵是对角的。在您的实现中,您将平均值和对角线协方差近似为:

mu = relu(x.dot(w_vae1))
sigma = relu(x.dot(w_vae2))

这看起来很好,但是在获取样本时(重新参数化技巧),不确定为什么要引入np.log2()。由于您使用的是ReLU()激活,您的sigma变量中可能会以0结束,当您使用np.log2(0)激活时,您将得到inf。我相信你是被一些可用的代码所激励的:

mu = relu(x.dot(w_vae1)) #same as yours
logOfSigma = x.dot(w_vae2) #you are forcing your network to learn log(sigma)

现在,由于您正在逼近sigma的对数,您可以允许您的输出为负,因为要得到sigma,您将执行类似于np.exp(logOfSigma)的操作,这将确保在对角线协方差矩阵中始终得到正值。现在要进行采样,您只需执行以下操作:

latent_code = mu + np.exp(logOfSigma)*epsilon_sample

希望这有帮助

相关问题 更多 >