Keras中的自定义丢失功能可以惩罚漏报

问题描述 投票:8回答:1

我正在研究一个医疗数据集,我试图减少假阴性。预测“实际上没有疾病时的疾病”对我来说是可以的,但预测“实际上没有疾病时没有疾病”。也就是说,我对FP没有问题,但没有FN

在做了一些研究之后,我发现了像Keeping higher learning rate for one classusing class weightsensemble learning with specificity/sensitivity等的方法。

我使用像class_weight = {0 : 0.3,1: 0.7}这样的类权重然后调用model.fit(class_weights=class_weight)来获得接近期望的结果。这给了我非常低的FN但是相当高的FP。我试图尽可能地降低FP,使FN保持在非常低的水平。

我正在努力使用Keras编写自定义丢失函数,这将帮助我惩罚假阴性。谢谢您的帮助。

machine-learning keras deep-learning gradient-descent loss-function
1个回答
0
投票

我将简要介绍一下我们试图解决的概念。

召回

从所有积极的方面来看,我们的模型预测有多少是积极的?

所有这些都是积极的=

我们的模型所说的是积极的=

由于召回与FN成反比,因此改善它会降低FN。

特异性

从所有负面的,我们的模型预测为负数多少?

所有这些都是负面的=

我们的模型所说的是负面=

由于召回与FP成反比,因此改善它会降低FP。

在您的下一次搜索或您执行的任何与分类相关的活动中,了解这些活动将为您提供沟通和理解的额外优势。


一个办法

所以。正如你们已经想到的那样,这两个概念是对立的。这意味着增加一个可能会减少另一个。

由于您希望调用优先级,但不希望在特异性方面过于宽松,因此可以将这两者与属性权重结合起来。遵循this answer中明确解释的内容:

import numpy as np
import keras.backend as K

def binary_recall_specificity(y_true, y_pred, recall_weight, spec_weight):

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

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

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

    specificity = TN / (TN + FP + K.epsilon())
    recall = TP / (TP + FN + K.epsilon())

    return 1.0 - (recall_weight*recall + spec_weight*specificity)

注意recall_weightspec_weight?它们是我们归因于每个指标的权重。对于分发惯例,它们应该总是添加到1.0¹,例如recall_weight=0.9specificity_weight=0.1。这里的目的是让您了解最适合您需求的比例。

但是Keras的损失函数必须只接收(y_true, y_pred)作为参数,所以让我们定义一个包装器:

# Our custom loss' wrapper
def custom_loss(recall_weight, spec_weight):

    def recall_spec_loss(y_true, y_pred):
        return binary_recall_specificity(y_true, y_pred, recall_weight, spec_weight)

    # Returns the (y_true, y_pred) loss function
    return recall_spec_loss

使用它,我们有

# Build model, add layers, etc
model = my_model
# Getting our loss function for specific weights
loss = custom_loss(recall_weight=0.9, spec_weight=0.1)
# Compiling the model with such loss
model.compile(loss=loss)

¹重量,加上,必须总1.0,因为如果recall=1.0specificity=1.0(完美的分数),公式

例如,应该给我们

显然,如果我们得到了满分,我们希望我们的损失等于0。

© www.soinside.com 2019 - 2024. All rights reserved.