Tensorflow 2.0错误,自定义损失函数

时间:2020-09-14 11:31:19

标签: tensorflow keras deep-learning tensorflow2.0 loss-function

我定义了一个损失函数,但是当我运行model.fit()时遇到了我无法解决的错误。

这是我的损失函数:

def l2_loss_eye_distance_normalised(y_actual, y_pred):
    #this loss function expects an exact, specific indexing order in the labels

    # the squared, ground truth, interocular distance
    eye_dst_vector = np.array([y_actual[0] - y_actual[2], y_actual[1] - y_actual[3]])
    denominator = kb.sum(kb.square(eye_dst_vector))

    #the squared distance between predition vector and ground truth vector
    dst_vec = y_actual - y_pred
    numerator = kb.sum(kb.square(dst_vec))

    return tf.cast(numerator / denominator, dtype="float32")

稍后在main()中,我使用以下命令编译模型:

model.compile(
        optimizer=tf.keras.optimizers.Adam(0.001),
        loss=l2_loss_eye_distance_normalised, #custom loss
        metrics=['mae', 'mse']
    )

当调用model.fit()时出现错误:

history = model.fit(
    train_ds,
    validation_data=val_ds,
    epochs=EPOCHS,
    verbose = 1
)

我认为我在自定义损失函数上犯了一个错误,但我不明白哪里出了问题。 有人可以帮忙吗? :)

Error Message

1 个答案:

答案 0 :(得分:0)

在您的方法中,您将进行一个while循环,在其中循环访问批处理维度。然而,这是非常低效和不必要的,并且更类似于您在python中而不是tensorflow上的想法。相反,您应该一次为每个批次进行每个计算。请记住,损失输出是单个标量(这就是为什么您收到错误消息“ expected non-tensor”的原因),因此无论如何最终都必须对批次进行求和。

假定,您的形状为(Batch, label)=(None, 4)(如果您有其他中间尺寸,例如由于一个序列,只需将它们添加到下面的所有索引中),即可:

left = tf.math.squared_difference(y_actual[:,0], y_actual[:,2] # shape: (Batch,)
right = tf.math.squared_difference(y_actual[:,1], y_actual[:,3] # shape: (Batch,)
denominator = left + right # shape: (Batch,)

从这里开始,所有内容都必须为(Batch, )形状:

dst_vec = tf.math.squared_difference(y_actual, y_pred) # shape: (Batch, 4)
numerator = tf.reduce_sum(dst_vec, axis=-1) # shape: (Batch,)

loss_for_each_batch = tf.cast(numerator / denominator, dtype="float32")

现在,如何从loss_for_each_batch中获得最终损失取决于您的设计,但是简单地累加单个损失将是正常方法:

return tf.reduce_sum(loss_for_each_batch)
相关问题