带范围选择的 Keras 自定义损失 - 独立处理值

Keras custom loss with range selection - treat values independently

我有一个自定义损失定义如下:

def custom_mse():
    def mse(y_true, y_pred):
        great = K.tf.greater(y_true,0.5)
        loss = K.square(tf.where(great, y_true, tf.zeros(tf.shape(y_true)))-tf.where(great, y_pred, tf.zeros(tf.shape(y_pred))))
        loss_low = K.square(y_true-y_pred)
        
        return loss+loss_low

这个损失是两个损失的总和,未受影响的预测和真实标签的 MSE,以及仅在真实标签中的值超过 0.5 的位置上的元素的 MSE。

这很完美,但现在我想做一些不同的事情。

我想创建一个将 0.01-0.2 范围内的值转换为 1 的损失,以便模型得到这些不正确的反馈(降低这些值的重要性更高)。从 线程我找到了如何 select 范围的方法:

lower_tensor = K.tf.greater(y_pred, 0.01)
upper_tensor = K.tf.less(y_pred, 0.2)
in_range = K.tf.logical_and(lower_tensor, upper_tensor)

但是我找不到将这些指数应用于原始张量的方法,因此在计算中它将作为一个来处理。我想做这样的事情(只是一个例子,这是行不通的):

tf.where(in_range, y_pred) = 1
loss = K.square(y_true-y_pred)

有办法实现吗?还是需要再分摊损失一起算?

您可以将 tf.wheretf.ones_like 和您的原始张量一起使用。

一个示例(y_pred 设置为 [0.0, 0.1, 0.8, 0.15]):

import tensorflow as tf

y_pred = tf.constant([0.0, 0.1, 0.8, 0.15])
lower_tensor = tf.greater(y_pred, 0.01)
upper_tensor = tf.less(y_pred, 0.2)
in_range = tf.logical_and(lower_tensor, upper_tensor)
# tf.where is (cond, tensor if cond is true, tensor if cond is false)
y_pred_w_ones = tf.where(in_range, tf.ones_like(y_pred), y_pred)

然后我们得到

>>> y_pred_w_ones
 <tf.Tensor: shape=(4,), dtype=float32, numpy=array([0. , 1. , 0.8, 1. ], dtype=float32)>