即使尺寸不匹配,自定义损失功能仍然有效

时间:2019-01-02 09:22:01

标签: tensorflow keras loss-function


我在以下模型中使用Keras / TF:

#include <stdio.h>

int main()
{
   int i,j,a[2][2];
   for(i=1;i<=2;i++)
   {
     for(j=1;j<=2;j++)
        scanf("%d\t",&a[i][j]);
    }

    printf("\n%d\t%d\n%d\t%d", a[1][1],a[1][2],a[2][1],a[2][2]);
}

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

  

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

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

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

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)

并编译模型:

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

起作用(或者至少没有给出错误)。有什么自动转换/截断方法吗?

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

此致, 逃跑

1 个答案:

答案 0 :(得分:3)

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

事实证明,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:True标签。 TensorFlow / Theano张量。

     

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

所以我发现这有点矛盾...

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

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

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