Пользовательская функция потерь в Keras, чтобы штрафовать ложные негативы - PullRequest
0 голосов
/ 08 октября 2018

Я работаю над набором медицинских данных, в котором я пытаюсь получить как можно меньше ложных негативов.Предсказание «болезни, когда на самом деле нет болезни» - это хорошо для меня, но предсказание «никакой болезни, когда на самом деле болезнь» - нет.То есть, я в порядке с FP, но не FN.

. После некоторых исследований я нашел такие способы, как Keeping higher learning rate for one class, using class weights, ensemble learning with specificity/sensitivity и т. Д.

* 1009.* Я достиг почти желаемого результата, используя веса классов, такие как class_weight = {0 : 0.3,1: 0.7}, а затем вызвал model.fit(class_weights=class_weight).Это дало мне очень низкий FN, но довольно высокий FP.Я пытаюсь максимально уменьшить FP, сохраняя FN очень низким.

Я изо всех сил пытаюсь написать пользовательскую функцию потерь , используя Keras, которая поможет мне штрафовать за ложные отрицания.Спасибо за помощь.

1 Ответ

0 голосов
/ 22 апреля 2019

Я кратко представлю концепции, которые мы пытаемся решить.

Напомним

Из всех , которые были положительными , сколько наша модель предсказала как положительные?

Все, что было положительным = positive

То, что наша модель сказала, было положительным = said positive

recall

Поскольку отзыв обратно пропорционален FN, улучшениеоно уменьшает FN.

Специфичность

Из всех , которые были отрицательными , сколько наша модель предсказала как отрицательную?

Все, что было отрицательным = negative

То, что наша модель сказала, было отрицательным = said negative

specificity

Поскольку отзыв является обратно пропорциональнымдо FP, улучшая его, уменьшает FP.

Во время следующих поисков или любой другой деятельности, связанной с классификацией, которую вы выполняете, зная, что это даст вам дополнительное преимущество в общении и понимании.


Решение

Итак.Эти две концепции, как вы уже поняли, являются противоположностями.Это означает, что увеличение одного может уменьшить другое .

Так как вы хотите приоритет при отзыве, но не хотите терять слишком много специфичности, выможно комбинировать как эти, так и веса атрибутов.После того, что ясно объяснено в этом ответе :

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_weight и spec_weight?Это веса, которые мы приписываем каждой метрике.В соответствии с соглашением о распространении они всегда должны добавляться к 1.0 ¹, например, recall_weight=0.9, specificity_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.0 и specificity=1.0 (идеальный результат), формула

loss1

Дадим нам, например,

loss2

Очевидно, что если бы мы получили идеальный результат, мы бы хотели, чтобы нашпотери равны 0.

...