Keras 自定义损失函数作为 True Negatives by (True Negatives plus False Positives)

数据挖掘 喀拉斯
2021-09-28 01:01:16

我有一些可以构建混淆矩阵的模型,尽管我需要一个自定义的损失函数,如下所示:

混淆矩阵

真阴性(TN):我们预测不是,但事实并非如此。

误报(FP):我们预测是,但事实并非如此。

我的损失函数应该是这样的:

           TN
  1 -  _________
        TN + FP 

如何在 Keras 中实现相同的功能:这里有自定义损失函数的解释:StackOverFlow

虽然,我不确定相同的差异部分会是什么样子。

图片来源:http ://www.dataschool.io/simple-guide-to-confusion-matrix-terminology/

2个回答

当您在训练期间使用上述解决方案时,它不起作用,因为这行会引发错误:

TN = np.logical_and(K.eval(y_true) == 0, K.eval(y_pred) == 0)

也许这可能是解决此问题的更好方法,您可以在每个 epoch 之后计算特异性并绘图!

def specificity(y_pred, y_true):
    """
    param:
    y_pred - Predicted labels
    y_true - True labels 
    Returns:
    Specificity score
    """
    neg_y_true = 1 - y_true
    neg_y_pred = 1 - y_pred
    fp = K.sum(neg_y_true * y_pred)
    tn = K.sum(neg_y_true * neg_y_pred)
    specificity = tn / (tn + fp + K.epsilon())
    return specificity

因此,您似乎想计算模型的特异性

TNR=TNN=TNTN+FP

因此,您需要一个可以进行预测的函数,计算真阴性和假阳性的数量,然后使用上面的等式计算特异性。这个函数的主体是从这里借来的,简单地修改为两个类。

import numpy as np
import keras.backend as K

def compute_binary_specificity(y_pred, y_true):
    """Compute the confusion matrix for a set of predictions.

    Parameters
    ----------
    y_pred   : predicted values for a batch if samples (must be binary: 0 or 1)
    y_true   : correct values for the set of samples used (must be binary: 0 or 1)

    Returns
    -------
    out : the specificity
    """

    check_binary(K.eval(y_true))    # must check that input values are 0 or 1
    check_binary(K.eval(y_pred))    # 

    TN = np.logical_and(K.eval(y_true) == 0, K.eval(y_pred) == 0)
    FP = np.logical_and(K.eval(y_true) == 0, K.eval(y_pred) == 1)

    # as Keras Tensors
    TN = K.sum(K.variable(TN))
    FP = K.sum(K.variable(FP))

    specificity = TN / (TN + FP + K.epsilon())
    return specificity

编辑:此函数给出的结果相当于该函数的 numpy 版本,并且经过测试可用于 2d、3d、4d 和 5d 数组。

正如您添加的链接所暗示的那样,您还必须创建一个包装函数以将此自定义函数用作 Keras 中的损失函数:

def specificity_loss_wrapper():
    """A wrapper to create and return a function which computes the specificity loss, as (1 - specificity)

    """
    # Define the function for your loss
    def specificity_loss(y_true, y_pred):
        return 1.0 - compute_binary_specificity(y_true, y_pred)

    return specificity_loss    # we return this function object

请注意,包装函数返回的特异性损失1specificity. 这也可以在第一个函数中执行——这应该很重要,我只是将特异性的计算与损失的计算分开。

然后可以这样使用:

# Create a Keras model object as usual
model = my_model()

# ... (add layers etc)

# Create the loss function object using the wrapper function above
spec_loss = specificity_loss_wrapper()

# compile model using the return los function object
model.compile(loss=spec_loss)

# ... train model as usual

此外,您可以尝试导入 Tensorflow 本身并使用其内置的 tf.confusion_matrix operation