neural-network - Keras 中 add_loss 函数的目的是什么?

标签 neural-network keras autoencoder

目前,我偶然发现了变分自动编码器,并尝试使用 keras 使它们在 MNIST 上工作。我在 github 上找到了一个教程.

我的问题涉及以下代码行:

# Build model
vae = Model(x, x_decoded_mean)

# Calculate custom loss
xent_loss = original_dim * metrics.binary_crossentropy(x, x_decoded_mean)
kl_loss = - 0.5 * K.sum(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1)
vae_loss = K.mean(xent_loss + kl_loss)

# Compile
vae.add_loss(vae_loss)
vae.compile(optimizer='rmsprop')

为什么使用 add_loss 而不是将其指定为编译选项?类似 vae.compile(optimizer='rmsprop', loss=vae_loss)似乎不起作用并引发以下错误:

ValueError: The model cannot be compiled because it has no loss to optimize.

此函数与自定义损失函数之间有什么区别,我可以将其添加为 Model.fit() 的参数?

提前致谢!

P.S.:我知道 github 上有几个关于这个的问题,但大多数都是开放的并且没有注释。如果这已经解决了,请分享链接!

编辑 1

我删除了将损失添加到模型的行,并使用了 compile 函数的 loss 参数。现在看起来像这样:

# Build model
vae = Model(x, x_decoded_mean)

# Calculate custom loss
xent_loss = original_dim * metrics.binary_crossentropy(x, x_decoded_mean)
kl_loss = - 0.5 * K.sum(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1)
vae_loss = K.mean(xent_loss + kl_loss)

# Compile
vae.compile(optimizer='rmsprop', loss=vae_loss)

这会引发一个类型错误:

TypeError: Using a 'tf.Tensor' as a Python 'bool' is not allowed. Use 'if t is not None:' instead of 'if t:' to test if a tensor is defined, and use TensorFlow ops such as tf.cond to execute subgraphs conditioned on the value of a tensor.

编辑 2

感谢@MarioZ 的努力,我找到了解决方法。

# Build model
vae = Model(x, x_decoded_mean)

# Calculate custom loss in separate function
def vae_loss(x, x_decoded_mean):
    xent_loss = original_dim * metrics.binary_crossentropy(x, x_decoded_mean)
    kl_loss = - 0.5 * K.sum(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1)
    vae_loss = K.mean(xent_loss + kl_loss)
    return vae_loss

# Compile
vae.compile(optimizer='rmsprop', loss=vae_loss)

...

vae.fit(x_train, 
    x_train,        # <-- did not need this previously
    shuffle=True,
    epochs=epochs,
    batch_size=batch_size,
    validation_data=(x_test, x_test))     # <-- worked with (x_test, None) before

由于一些奇怪的原因,我不得不在拟合模型时明确指定 y 和 y_test 。本来,我不需要这样做。生产的 sample 对我来说似乎是合理的。

虽然我可以解决这个问题,但我仍然不知道这两种方法的区别和缺点是什么(除了需要不同的语法)。有人可以给我更多的见解吗?

最佳答案

我将尝试回答为什么 model.add_loss() 的原始问题正在使用而不是为 model.compile(loss=...) 指定自定义损失函数.

Keras 中的所有损失函数始终采用两个参数 y_truey_pred .看看 Keras 中可用的各种标准损失函数的定义,它们都有这两个参数。它们是“目标”(许多教科书中的 Y 变量)和模型的实际输出。大多数标准损失函数可以写成这两个张量的表达式。但是一些更复杂的损失不能这样写。对于您的 VAE 示例,情况就是这样,因为损失函数还取决于附加张量,即 z_log_varz_mean ,这对损失函数不可用。使用 model.add_loss()没有这样的限制,并允许您编写依赖于许多其他张量的更复杂的损失,但它具有更依赖模型的不便,而标准损失函数仅适用于任何模型。

(注意:此处其他答案中提出的代码有些作弊,因为它们只是使用全局变量来潜入额外的必需依赖项。这使得损失函数在数学意义上不是真正的函数。我认为这是很多不太干净的代码,我希望它更容易出错。)

关于neural-network - Keras 中 add_loss 函数的目的是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50063613/

相关文章:

python - 在 Python 中使用 caffe.NetSpec() 时,train.prototxt 中的两个顶部 blob

neural-network - 神经网络如何知道它从行动中获得了哪些奖励?

python - 无法在 Tensorflow 2.0 中使用 vggface-keras

python - 操纵神经网络的输出

python - 如何定义自动编码器使用的初始权重?

opencv - 将openCV与openVINO一起使用的正确方法是什么?

python - 在 keras 中定义模型(include_top = True)

python - 卷积自动编码器图像尺寸误差

python - 指定 seq2seq 自动编码器。 RepeatVector 有什么作用?批量学习对预测输出有什么影响?

python - 交叉熵对具有相同分布的向量产生不同的结果