Keras 中的自定义损失函数以惩罚误报 [英] Custom loss function in Keras to penalize false negatives

查看:46
本文介绍了Keras 中的自定义损失函数以惩罚误报的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am working on a medical dataset where I am trying to have as less false negatives as possible. A prediction of "disease when actually no disease" is okay for me but a prediction "no disease when actually a disease" is not. That is, I am okay with FP but not FN.

经过一番研究,我发现了一些方法,比如保持一个班级的更高学习率使用班级权重具有特异性/敏感性的集成学习代码>等

After doing some research, I found out ways like Keeping higher learning rate for one class, using class weights,ensemble learning with specificity/sensitivity etc.

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

I achieved the near desired result using class weights like class_weight = {0 : 0.3,1: 0.7} and then calling the model.fit(class_weights=class_weight). This gave me very low FN but a pretty high FP. I am trying to reduce FP as much as possible keeping FN very low.

我正在努力使用 Keras 编写一个自定义损失函数,这将帮助我惩罚误报.感谢您的帮助.

I am struggling to write a custom loss function using Keras which will help me to penalize the false negatives. Thanks for the help.

推荐答案

我将简要介绍我们试图解决的概念.

I'll briefly introduce the concepts we're trying to tackle.

所有阳性,我们的模型预测有多少是阳性的?

From all that were positive, how many did our model predict as positive?

所有都是正面的 =

我们的模型所说的是肯定的 =

What our model said were positive =

由于召回率与 FN 成反比,提高它会降低 FN.

Since recall is inversely proportional to FN, improving it decreases FN.

所有那些否定,我们的模型预测有多少是否定的?

From all that were negative, how many did our model predict as negative?

所有负面信息 =

我们的模型所说的是否定的 =

What our model said were negative =

由于特异性与 FP 成反比,提高特异性会降低 FP.

Since specificity is inversely proportional to FP, improving it decreases FP.

在您的下一次搜索或您执行的任何与分类相关的活动中,了解这些将使您在沟通和理解方面获得额外优势.

In your next searches, or whatever classification-related activity you perform, knowing these is going to give you an extra edge in communication and understanding.

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

So. These two concepts, as you mas have figured out already, are opposites. This means that increasing one is likely to decrease the other.

由于您希望回忆具有优先权,但又不想失去太多的特异性,您可以将这两者和属性权重结合起来.遵循 这个答案:

Since you want priority on recall, but don't want to loose too much in specificity, you can combine both of those and attribute weights. Following what's clearly explained in 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.这里的目的是让您看看什么比例最适合您的需求.

Notice recall_weight and spec_weight? They're weights we're attributing to each of the metrics. For distribution convention, they should always add to 1.0¹, e.g. recall_weight=0.9, specificity_weight=0.1. The intention here is for you to see what proportion best suits your needs.

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

But Keras' loss functions must only receive (y_true, y_pred) as arguments, so let's define a wrapper:

# 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(完美分数),公式

¹ The weights, added, must total 1.0, because in case both recall=1.0 and specificity=1.0 (the perfect score), the formula

应该给我们,例如,

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

Clearly, if we got the perfect score, we'd want our loss to equal 0.

这篇关于Keras 中的自定义损失函数以惩罚误报的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆