对于变异型自动编码器,重建损失应该计算为图像的总和还是平均值? 例子问题是后部塌陷实验与推广

如何解决对于变异型自动编码器,重建损失应该计算为图像的总和还是平均值? 例子问题是后部塌陷实验与推广

我正在关注此变体自动编码器教程:https://keras.io/examples/generative/vae/

我知道VAE的损失函数由比较原始图像和重建的重建损失以及KL损失组成。但是,对于重建损失以及它是在整个图像上(平方差的总和)还是在每个像素上(平方差的平均和),我有些困惑。我的理解是重建损失应该是每个像素(MSE),但是我要遵循的示例代码将MSE乘以28 x 28,即MNIST图像尺寸。那是对的吗?此外,我的假设是,这将使重建损失项比KL损失大得多,我不确定我们是否想要。

我尝试删除(28x28)的乘法,但这导致重建效果极差。基本上,无论输入如何,所有重建看起来都是相同的。我可以使用lambda参数来捕获kl散度与重建之间的折衷,还是不正确,因为损失具有精确的导数(而不是仅仅添加正则化罚分)。

reconstruction_loss = tf.reduce_mean(
    keras.losses.binary_crossentropy(data,reconstruction)
)
reconstruction_loss *= 28 * 28
kl_loss = 1 + z_log_var - tf.square(z_mean) - tf.exp(z_log_var)
kl_loss = tf.reduce_mean(kl_loss)
kl_loss *= -0.5
total_loss = reconstruction_loss + kl_loss

解决方法

实际上不需要乘以像素数。但是,是否这样做会影响拟合算法相对于其他超级参数的行为:lambda参数和学习率。本质上,如果您希望将乘积除以28 x 28,但保持相同的拟合行为,则应将lambda除以28 x 28,然后将学习率乘以28 x28。我认为您已经在采用这种方法了问题,而您缺少的是对学习速度的调整。

,

例子

我熟悉那个例子,我认为 28x28 乘数是合理的,因为操作 tf.reduce_mean(kl_loss) 取图像中所有像素的平均损失,这将导致在 0 到 1 之间的数字中,然后将其乘以像素数。这是带有用于创建 VAE 的外部训练循环的 another take

问题是后部塌陷

以上不会成为问题,因为它只是乘以一个常数,如果不是因为您指出 KL 散度 项。 KL 损失充当正则化器,惩罚潜在变量概率分布,当使用高斯组合进行采样时,这些概率分布与编码器创建的样本不同。自然地,问题出现了,重建损失应该是多少,惩罚应该是多少。这是一个研究领域。考虑 β-VAE,据称它通过增加 KL-loss 的重要性来解开表征,另一方面,增加 β 太多,你会得到一种称为后验的现象折叠 Re-balancing Variational Autoencoder Loss for Molecule Sequence Generationβ 限制为 0.1 以避免该问题。但它甚至可能不像 The Usual Suspects? Reassessing Blame for VAE Posterior Collapse 中解释的那么简单。 Diagnosing and Enhancing VAE Models 中提出了一个彻底的解决方案。虽然 Balancing reconstruction error and Kullback-Leibler divergence in Variational Autoencoders 建议有一种更简单(更好)的确定性方法。

实验与推广

对于像 Minst 这样简单的东西,特别是那个例子,尝试试验。保留 28x28 项,并将 kl_loss 任意乘以常数 B,其中 0

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?