Tensorflow 2.0 错误,自定义损失函数
Error with Tensorflow 2.0, Custom 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
在您的方法中,您将继续执行一个 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)
我定义了一个损失函数,但是当我 运行 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
在您的方法中,您将继续执行一个 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)