Keras中add_loss函数的作用是什么?
0 1397
0

我偶然发现了变种自动编码器,并试图使它们使用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()的参数吗?

编辑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:

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 functiondef 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) 

由于某些原因,我在拟合模型时必须明确指定y和y_test。最初,我不需要这样做。产生的样本对我来说似乎很合理。

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

收藏
2021-02-26 10:16 更新 anna •  5050
共 1 个回答
高赞 时间
0

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

Keras中的所有损失函数总是采取两个参数y_true和y_pred。 看看Keras中可用的各种标准损失函数的定义,它们都有这两个参数。 它们是“目标”(许多教科书中的Y变量)和模型的实际输出。大多数标准损失函数可以写成这两个张量的表达式。 但一些更复杂的损失不能用这种方式来写。

对于VAE示例,情况就是这样,因为损失函数还依赖于额外的张量,即z_log_var和z_mean,这些张量不可用于损失函数。 使用model.add_loss()没有这样的限制,允许你编写依赖于许多其他张量的、更复杂的损失,但它有更多依赖于模型的不便,而标准损失函数适用于任何模型。

Via:https://stackoverflow.com/a/52683522/14964791

收藏
2021-02-26 10:55 更新 karry •  4552