为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

回首忆惘然 2022-06-02 15:26:32
我正在尝试在标签可能非常稀疏的地方分割数据。因此,我只想计算至少具有一个非零值的列中的梯度。我已经尝试了一些方法,其中我应用了一个额外的输入,即这些非零列的掩码,但鉴于所有必要的信息已经包含在 中y_true,只查看y_true查找掩码的方法肯定会更可取。如果我用 numpy 实现它,它可能看起来像这样: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_truey_pred在这个例子中是矢量化的 2D 图像。如何将其“转化”为可微分的 Keras 损失函数?
查看完整描述

1 回答

?
繁星点点滴滴

TA贡献1803条经验 获得超3个赞

使用tf- 兼容的操作,通过tf和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

我不确定您的问题的确切维度规格,但损失必须评估为单个值 - 上面没有,因为您正在传递多维预测和标签。要减少暗淡,请用 eg 包裹上面的 return 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

(最后,请注意,这种稀疏性会通过从总标签/预测计数中排除全零列来偏置损失;如果不希望,您可以通过K.sumand K.shapeor进行平均K.size)


查看完整回答
反对 回复 2022-06-02
  • 1 回答
  • 0 关注
  • 127 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信