【问题标题】:Custom loss function works even though dimensions mismatch即使尺寸不匹配,自定义损失函数也有效
【发布时间】:2019-05-28 22:53:53
【问题描述】:


我将 Keras/TF 与以下模型一起使用:

conv = Conv2D(4, 3, activation = None, use_bias=True)(inputs)   
conv = Conv2D(2, 1, activation = None, use_bias=True)(conv)
model = Model(input = inputs, output = conv)
model.compile(optimizer=Adam(lr=1e-4), loss=keras.losses.mean_absolute_error)

在 model.fit 中,我收到一条错误消息:

ValueError:检查目标时出错:预期 conv2d_2 有 形状 (300, 320, 2) 但得到了形状 (300, 320, 1) 的数组

这符合预期,因为目标是单通道图像,而模型中的最后一层有 2 个通道。

我不明白为什么当我使用自定义损失函数时:

def my_loss2(y_true, y_pred):
    return keras.losses.mean_absolute_error(y_true, y_pred)

并编译模型:

model.compile(optimizer = Adam(lr=1e-4), loss=my_loss2)

确实工作(或者至少没有给出错误)。是否正在进行任何类型的自动转换/截断?

我正在使用 TF (CPU) 1.12.0 和 Keras 2.2.2

真诚地, 埃拉德

【问题讨论】:

  • 这很有趣,你确定除了损失函数之外没有任何其他改变,因为在损失周围添加一个包装器,不应该真正改变任何东西。
  • 您使用的是哪个 keras 版本?对于 keras 2.2.2,我无法确认这一点。 model.compile 不会给我任何损失的错误。但是,当我调用model.fit 时,我确实得到了他们俩的错误。实际上,在您发布的代码中,model.compile 没有您的目标形状的概念,那么它应该如何检测该错误?
  • 对不起,我没有在帖子中说明这一点。错误当然发生在 model.fit 中(我会更新帖子)。我使用的是 keras 2.2.2 和 tensorflow (cpu) 1.12.0,哪个版本给了你一致的行为?
  • @Marumba 我刚刚意识到自定义丢失的错误是不同的。发生这种情况是因为我缺少的倒数第二个维度的不一致。如果我解决了这个问题并且所有尺寸都相同,除了最后一个,fit 确实通过了,没有任何自定义丢失错误。显然,最后一个维度正在进行一些广播,但这并不能解释为什么内置损失没有广播......我假设内置损失fit正在做一些手动形状检查...

标签: tensorflow keras loss-function


【解决方案1】:

为什么内置损失和自定义损失的行为不同?

事实证明,Keras 正在对损失模块中定义的内置函数执行前期形状检查。

fit调用的Model._standardize_user_data的源代码中,我发现了这样一条注释:

# If `loss_fn` is not a function (e.g. callable class)
# or if it not in the `losses` module, then
# it is a user-defined loss and we make no assumptions
# about it.

在围绕该注释的代码中,您可以看到确实,根据损失函数的类型(内置或自定义),输出形状要么传递给 standardize_input_data 的内部调用,要么不传递。如果输出形状通过,standardize_input_data 将引发您收到的错误消息。

而且我认为这种行为是有道理的:如果不知道损失函数的实现,就无法知道它的形状要求。有人可能会发明一些需要不同形状的损失函数。另一方面,docs 明确表示损失函数的参数必须具有相同的形状:

y_true:真实标签。 TensorFlow/Theano 张量。

y_pred:预测。与 y_true 形状相同的 TensorFlow/Theano 张量。

所以我觉得这有点不一致......

为什么您的自定义损失函数适用于不兼容的形状?

如果您提供自定义损失,它可能仍然有效,即使形状不完全匹配。在您的情况下,只有最后一个维度不同,我很确定 broadcasting 是正在发生的事情。您的目标的最后一个维度将被复制。

在许多情况下,广播非常有用。然而,这里可能不会,因为它隐藏了一个逻辑错误。

【讨论】:

  • 这是新的,我想。而且很有趣。
猜你喜欢
  • 2019-08-13
  • 1970-01-01
  • 2019-11-01
  • 2018-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-19
  • 2012-09-11
相关资源
最近更新 更多