当不使用KL散度项时,VAE几乎能很好地重建原始图像,但当存在随机噪声时,VAE不能很好地重建新图像。
当使用KL散度项时,VAE在重建和生成图像时给出相同的怪异输出。
下面是损失函数的pytorch代码:
def loss_function(recon_x, x, mu, logvar):
BCE = F.binary_cross_entropy(recon_x, x.view(-1, 784), size_average=True)
KLD = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp())
return (BCE+KLD)
recon_x是重建图像,x是original_image,μ是平均向量,而logvar是包含方差的对数的向量。
这里出了什么问题?提前感谢:)
4条答案
按热度按时间py49o6xq1#
一个可能的原因是两个损失之间的数字不平衡,您的
BCE
损失计算为整个批次的平均值(c.f.size_average=True
),而KLD
损失是总和。xcitsw882#
用KLD乘以0.0001就可以了。生成的图像有点失真,但相似性问题得到了解决。
kuhbmx9i3#
是,尝试使用KLD损失项的不同权重因子。降低KLD损失项的权重可解决CelebA数据集(http://mmlab.ie.cuhk.edu.hk/projects/CelebA.html)中的相同重建输出问题。
bakd9h0s4#
这有很多可能的原因。正如benjaminplanche所说,您需要使用.mean而不是.sum约简。此外,KLD项权重可能因架构和数据集的不同而不同。因此,请尝试不同的权重,并查看重建损失和潜在空间以进行决定。重建损失(输出质量)和KLD项之间存在一个权衡,KLD项会迫使模型形成高斯型潜在空间。
为了评估VAE的不同方面,我用不同的KLD项权重训练了Vanilla自动编码器和VAE。注意,我使用MNIST手写数字数据集来训练输入大小为784=28*28和潜在大小为30维的网络。虽然对于[0,1]范围内的数据样本,我们通常使用Sigmoid激活函数,但出于实验原因,我使用了Tanh。
Vanilla自动编码器:
然后,我实现了VAE模型,如下面的代码块所示。我用集合{0.5,1,5}中的不同KLD权重训练了这个模型。
在这里你可以看到不同模型的输出结果。我还使用sklearn.manifold.TSNE变换在2D中可视化了30维的潜在空间。
我们观察到具有30 D瓶颈尺寸的vanilla自动编码器的低损失值,这导致高质量的重建图像。虽然损失值在VAE中增加,但VAE安排了潜在空间,使得不同类别的潜在表示之间的间隙减小。这意味着我们可以更好地操纵由于VAE在本征空间遵循各向同性多元正态分布,我们可以通过从潜在空间中提取比Vanilla自动编码器质量更高的样本来生成新的不可见图像。2然而,重建质量降低(损失值增加)因为损失函数是待优化的MSE和KLD项的加权组合当我们增加KLD权重时,通过牺牲重构质量,我们实现了更紧凑的更接近先验分布的潜在空间。