下面是当前的函数。这里,它从MSE中删除y_true小于阈值(这里为0.1)的任何值
def my_loss(y_true,y_pred):
loss = tf.square(y_true-y_pred)
# if any y_true is less than a threshold (say 0.1)
# the element is removed from loss, and does not affect MSE
loss = tf.where(y_true<0.1)
# return mean of losses
return tf.reduce_mean(loss)
这一个可以编译,但是网络没有很好地预测0。相反,我只想消除那些y_true和y_pred都小于某个阈值的值。这是因为它需要先学习如何预测0,然后在以后的训练中忽略这些点
然而,这并不编译
def my_better_loss(y_true,y_pred):
loss = tf.square(y_true-y_pred)
# remove all elements where BOTH y_true & y_pred < threshold
loss = tf.where(y_true<0.1 and y_pred<0.1)
# return mean of losses
return tf.reduce_mean(loss)
它会导致以下错误
(0) Invalid argument: The second input must be a scalar, but it has shape [25,60,60]
[[{{node replica_1/customMSE/cond/switch_pred/_51}}]]
(1) Invalid argument: The second input must be a scalar, but it has shape [25,60,60]
[[{{node replica_1/customMSE/cond/switch_pred/_51}}]]
[[customMSE/cond/Squeeze/_59]]
(2) Invalid argument: The second input must be a scalar, but it has shape [25,60,60]
[[{{node replica_1/customMSE/cond/replica_1/customMSE/Less/_55}}]]
0 successful operations.
0 derived errors ignored. [Op:__inference_train_function_4715]
Function call stack:
train_function -> train_function -> train_function
编辑:
更具体地说。假设我们的阈值为0.5:
y_true = [0.3, 0.4, 0.6, 0.7]
y_pred = [0.2, 0.7, 0.5, 1]
然后,由于y_pred[0]和y_true[0]都小于阈值,因此损失函数将在删除第一个元素的情况下计算mse
# MSE would be computed between
y_true = [0.4, 0.6, 0.7]
#and
y_pred = [0.7, 0.5, 1]
您似乎对
tf.where
用法感到困惑。从documentation可以看出,tf.where应该采用三个参数,否则它将简单地返回None
,如这里所述这就是为什么你的损失无助于学习任何东西,因为它总是会返回
None
不管怎样对于你的问题,如果你想检查这两个条件,然后暗示损失,这是你应该怎么做
假设
y_true!=0
和y_pred!=0
分别给出损失some_loss1
和some_loss2
,那么总损失可以通过嵌套tf.where
计算为这将惩罚双方
此外,如果要将此损失添加到MSE损失中,请创建不同的变量名称,因为它将已获得的MSE值添加到此掩码损失中
如果在转换为图形模式的代码中使用python short-circuit
and
运算符,则大多数情况下会导致不良行为或错误,因为python short-circuitand
运算符不能重载。要对张量执行元素和运算,请使用tf.math.logical_and
此外
tf.where
在这里是不必要的,而且速度可能较慢。首选掩蔽。示例代码:相关问题 更多 >
编程相关推荐