我试图将自定义损失mse函数与keras结合使用,以更加强调DNN模型的小价值。
我确实尝试过这样的事情:
import keras.backend as K
def scaled_mse(y_true,y_pred):
loss = K.square(y_pred - y_true)
if y_true>0.1:
loss=loss/K.abs(y_true)
return loss
我的ML模型的输入为41值。输出仅为1个值。
但是它返回此错误:
OperatorNotAllowedInGraphError:在图形执行中不允许将tf.Tensor
用作Python bool
。使用急切执行或使用@ tf.function装饰此功能。
感谢您的帮助!
答案 0 :(得分:1)
您的代码存在的问题是if
运算符对于每个keras后端都是不可区分的。但是,如果您考虑此操作的区别,那就很简单了。仅当条件评估为True时,梯度才依赖于一个项,如果条件评估为False,则梯度也依赖于另一项。因此,修复应该很简单。我相信Keras后端提供了switch()
操作,它本质上是条件语句的可区分形式。尝试改用它。
switch()
包含三个参数:第一个是条件表达式,第二个是张量,如果条件的值为真,则从中取值;第三个是张量,如果条件的值等于,则取值。假。因此您的代码可能看起来像这样:
import keras.backend as K
def scaled_mse(y_true,y_pred):
# both loss and scale loss are size 41
loss = K.square(y_pred - y_true)
scaled_loss = loss/K.abs(y_true)
# first arg (bool expression) will evaluate to a bool tensor of size 41,
# which then indicates from which tensor to select the value for each
# element of the output tensor
scale_mse_loss = K.switch((y_true > 0.1),scaled_loss,loss)
return scale_mse_loss