【发布时间】:2019-10-13 03:38:42
【问题描述】:
我正在尝试在 Keras 中实现 softmax 交叉熵损失。损失应该只考虑标签为 1 或 0 的样本,而忽略标签为 -1 的样本(即缺少标签)。我找到了一个 binary_crossentropy 函数,但我无法为它实现 softmax 版本。
这是binary_crossentropy:
def binary_crossentropy(y_true, y_pred):
return K.mean(K.binary_crossentropy(tf.multiply(y_pred, tf.cast(tf.not_equal(y_true, -1), tf.float32)),
tf.multiply(y_true, tf.cast(tf.not_equal(y_true, -1), tf.float32))), axis=-1)
我尝试用K.categorical_crossentropy 更改K.binary_crossentropy() 函数,但这只会在计算损失时给我“nan”。
如何在 Keras(Tensorflow 后端)上实现这一点?
编辑
在this answer中,作者建议使用sparse_crossentropy,但是我在编译模型时遇到了错误:
使用sparse_categorical_crossentropy 和boolean_mask
def sparse_crossentropy_masked(y_true, y_pred):
y_true_masked = tf.boolean_mask(y_true, tf.not_equal(y_true, -1))
y_pred_masked = tf.boolean_mask(y_pred, tf.not_equal(y_true, -1))
return K.mean(K.sparse_categorical_crossentropy(y_true_masked, y_pred_masked))
测试用例
y_true = tf.constant(np.array([0.,1.,2., -1]))
y_pred = tf.constant(np.array([[1.,0.,0.], [0.,1.,0.], [0.,0.,1.], [0.,0.,1.]]))
loss_op = sparse_crossentropy_masked(y, y_hat)
y_true_1 = tf.constant(np.array([0.,1.,2.]))
y_pred_1 = tf.constant(np.array([[1.,0.,0.], [0.,1.,0.], [0.,0.,1.]]))
loss_1_op = sparse_crossentropy_masked(y_true_1, y_pred_1)
with tf.Session() as sess:
loss, loss_1 = sess.run([loss_op, loss_1_op])
assert loss == loss_1
model.compile(loss=sparse_crossentropy_masked)
### TypeError: int returned non-int (type NoneType
【问题讨论】:
-
是否有特别的理由让这些样本在网络中输入?为什么不简单地在你的训练集中摆脱它?
-
@ThibaultBacqueyrisses 每个样本都与 1 个或多个输出相关联。因此,如果我将它们从训练中删除,我会丢失许多标签的信息。
-
@MarcosSantana,请考虑 mujjiga 的回答和您提到的错误更新您的问题
标签: tensorflow machine-learning keras deep-learning loss-function