keras中的自定义二进制交叉熵损失,忽略了没有非零值的列

时间:2019-09-21 13:31:59

标签: python tensorflow keras casting

我正在尝试对标签可能非常稀疏的数据进行分段。因此,我只想计算至少具有一个非零值的列中的梯度。

我尝试了一些方法,在这些方法中应用了额外的输入,这些输入是这些非零列的掩码,但是鉴于所有必需的信息已经包含在y_true中,因此该方法仅查看{{1 }}寻找面具绝对是可取的。

如果我用numpy实现它,它可能看起来像这样:

y_true

def loss(y_true, y_pred): indices = np.where(np.sum(y_true, axis=1) > 0) return binary_crossentropy(y_true[indices], y_pred[indices]) y_true在此示例中是矢量化2D图像。

如何将其“转换”为可区分的Keras损失函数?

1 个答案:

答案 0 :(得分:0)

通过tftf使用keras.backend兼容的操作:

import tensorflow as tf
import keras.backend as K
from keras.losses import binary_crossentropy

def custom_loss(y_true, y_pred):
    indices = K.squeeze(tf.where(K.sum(y_true, axis=1) > 0))
    y_true_sparse = K.cast(K.gather(y_true, indices), dtype='float32')
    y_pred_sparse = K.cast(K.gather(y_pred, indices), dtype='float32')
    return binary_crossentropy(y_true_sparse, y_pred_sparse) # returns a tensor

我不确定您问题的确切尺寸规格,但是损失必须评估为单个值-上面的值不是,因为您正在传递多维预测和标签。为了减少暗淡,请在上方用例如K.mean。示例:

y_true = np.random.randint(0,2,(10,2))
y_pred = np.abs(np.random.randn(10,2))
y_pred /= np.max(y_pred) # scale between 0 and 1

print(K.get_value(custom_loss(y_true, y_pred))) # get_value evaluates returned tensor
print(K.get_value(K.mean(custom_loss(y_true, y_pred))
>> [1.1489482  1.2705883  0.76229745  5.101402  3.1309896] # sparse; 5 / 10 results
>> 2.28284 # single value, as required

(最后,请注意,这种稀疏性会通过从总标签/ pred计数中排除全零列来偏向于损失;如果不希望,则可以通过K.sumK.shape或{{1 }})