如何用MSE创建一个损失函数,该函数使用tf.where()来忽略某些元素



这是当前的函数。在这里,它从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]

那么损失函数将计算除去第一个元素的mse,因为y_pred[0]和y_true[0]都小于阈值。

# MSE would be computed between
y_true = [0.4, 0.6, 0.7]
#and
y_pred = [0.7, 0.5, 1]

大多数情况下,如果您在转换为图形模式的代码中使用python短路and运算符,则会导致不良行为或错误,因为python短路and运算符不能重载。要对张量进行单元和运算,请使用tf.math.logical_and

此外,tf.where在这里是不必要的,它可能是较慢的。屏蔽是首选。示例代码:

@tf.function
def better_loss(y_true,y_pred):
loss = tf.square(y_true - y_pred)
# ignore elements where BOTH y_true & y_pred < 0.1
mask = tf.cast(tf.logical_or(y_true >= 0.1, y_pred >= 0.1) ,tf.float32)
loss *= mask
return tf.reduce_sum(loss) / tf.reduce_sum(mask)

你似乎混淆了tf.where的用法。从文档中可以看出。where应该接受三个参数,否则它将简单地返回这里提到的None

tf.where(
condition, x=None, y=None, name=None
)

这就是为什么loss对学习没有任何帮助,因为无论如何它总是返回None

对于你的问题,如果你想检查这两个条件,然后暗示损失,你应该这样做。

假设对于y_true!=0y_pred!=0,你想分别给出some_loss1some_loss2的损失,那么总损失可以通过将tf.where嵌套为

来计算。
some_loss1=tf.constant(1000.0) #say
some_loss12=tf.constant(1000.0) #say
loss = tf.where(y_pred<0.1,tf.where(y_true<0.1,tf.constant(0.0),some_loss1),some_loss2)

这将惩罚y_pred and y_true

另外,如果您想将此损失添加到MSE损失中,则创建不同的变量名,因为它将已经获得的MSE值辞去到此掩码损失中。

相关内容

  • 没有找到相关文章

最新更新