自定义keras损失函数二进制交叉熵给出了不正确的结果



任何人都有一个令人信服的解决方案来让custom_binarycrossentry发挥作用吗?

我尝试了所有可能的方法(甚至使整个训练数据大小与细菌大小相同,以消除批量处理过程中对全局平均的依赖

我的crustom二进制交叉熵代码如下

def _loss_tensor(y_true, y_pred):
y_pred = K.clip(y_pred, _EPSILON, 1.0-_EPSILON)
out = (y_true * K.log(y_pred) + (1.0 - y_true) * K.log(1.0 - y_pred))
return -K.mean(out)
def _loss_tensor2(y_true, y_pred):
y_pred = K.clip(y_pred, _EPSILON, 1.0-_EPSILON)
out = -(y_true * K.log(y_pred) + -(1.0 - y_true) * K.log(1.0 - y_pred))
return out
def _loss_tensor2(y_true, y_pred):
loss1 = K.binary_crossentropy(y_true, y_pred)
return loss1

这些方法都不起作用。即使我在返回自定义损失函数的结果之前执行K.mean((,它也不起作用。

我无法理解使用loss='binary_crossentropture'的特殊功能。当我使用我的自定义损失函数时,训练很糟糕,它确实按预期工作。

我需要我的自定义损失函数来根据错误操作损失函数,并对特定类型的分类错误进行更多惩罚。

我已经找到了一种满足这一需求的方法,并在这里发布了同样的方法:https://github.com/keras-team/keras/issues/4108

然而,为什么内置函数的性能与显式公式方法明显不同尚不清楚。然而,我认为这主要是由于对y_pred的概率值的上界和下界的处理。

def custom_binary_loss(y_true, y_pred): 
# https://github.com/tensorflow/tensorflow/blob/v2.3.1/tensorflow/python/keras/backend.py#L4826
y_pred = K.clip(y_pred, K.epsilon(), 1 - K.epsilon())

term_0 = (1 - y_true) * K.log(1 - y_pred + K.epsilon())  # Cancels out when target is 1 
term_1 = y_true * K.log(y_pred + K.epsilon()) # Cancels out when target is 0
return -K.mean(term_0 + term_1, axis=1)

我在编写自定义BCE时也遇到了同样的问题。这是我的解决方案:

def get_custom_bce(epsilon = 1e-2):
def custom_bce(y_true, y_pred):
return -tf.math.reduce_mean(y_true * tf.math.log(tf.math.maximum(y_pred, tf.constant(epsilon))) + (1. - y_true) * tf.math.log(tf.math.maximum(1. - y_pred, tf.constant(epsilon))))
return custom_bce

很抱歉,我对Keras后端不太熟悉,但我相信它们是可互换的。顺便说一句,这是指在乙状结肠激活后使用。

最新更新