我定义了一个损失函数,但是当我运行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
)
我认为我在自定义损失函数上犯了一个错误,但我不明白哪里出了问题。 有人可以帮忙吗? :)
答案 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)