Comment calculer la ROC (Receiving Operating characteristic) et l ' AUC dans le kéras?

j'ai un modèle de classification binaire multi-sortie(200) que j'ai écrit dans keras.

dans ce modèle, je veux ajouter des mesures supplémentaires telles que ROC et AUC, mais à ma connaissance keras ne dispose pas de fonctions métriques intégrées ROC et AUC.

j'ai essayé D'importer des fonctions ROC, AUC de scikit-learn

from sklearn.metrics import roc_curve, auc
from keras.models import Sequential
from keras.layers import Dense
.
.
.
model.add(Dense(200, activation='relu'))
model.add(Dense(300, activation='relu'))
model.add(Dense(400, activation='relu'))
model.add(Dense(300, activation='relu'))
model.add(Dense(200,init='normal', activation='softmax')) #outputlayer

model.compile(loss='categorical_crossentropy', optimizer='adam',metrics=['accuracy','roc_curve','auc'])

mais il donne cette erreur:

Exception: non valide métrique: roc_curve

comment ajouter ROC, AUC à keras?

26
demandé sur icc97 2016-12-08 08:44:45

6 réponses

en raison de cela, vous ne pouvez pas calculer ROC&AUC par mini-lots, vous pouvez seulement le calculer à la fin d'une époque. Il y a une solution de jamartinh, je patch les codes ci-dessous pour votre commodité:

from sklearn.metrics import roc_auc_score
from keras.callbacks import Callback
class roc_callback(Callback):
    def __init__(self,training_data,validation_data):
        self.x = training_data[0]
        self.y = training_data[1]
        self.x_val = validation_data[0]
        self.y_val = validation_data[1]


    def on_train_begin(self, logs={}):
        return

    def on_train_end(self, logs={}):
        return

    def on_epoch_begin(self, epoch, logs={}):
        return

    def on_epoch_end(self, epoch, logs={}):
        y_pred = self.model.predict(self.x)
        roc = roc_auc_score(self.y, y_pred)
        y_pred_val = self.model.predict(self.x_val)
        roc_val = roc_auc_score(self.y_val, y_pred_val)
        print('\rroc-auc: %s - roc-auc_val: %s' % (str(round(roc,4)),str(round(roc_val,4))),end=100*' '+'\n')
        return

    def on_batch_begin(self, batch, logs={}):
        return

    def on_batch_end(self, batch, logs={}):
        return

model.fit(X_train, y_train, validation_data=(X_test, y_test), callbacks=[roc_callback(training_data=(X_train, y_train),validation_data=(X_test, y_test))])

une manière plus hackable en utilisant tf.contrib.metrics.streaming_auc:

import numpy as np
import tensorflow as tf
from sklearn.metrics import roc_auc_score
from sklearn.datasets import make_classification
from keras.models import Sequential
from keras.layers import Dense
from keras.utils import np_utils
from keras.callbacks import Callback, EarlyStopping


# define roc_callback, inspired by https://github.com/keras-team/keras/issues/6050#issuecomment-329996505
def auc_roc(y_true, y_pred):
    # any tensorflow metric
    value, update_op = tf.contrib.metrics.streaming_auc(y_pred, y_true)

    # find all variables created for this metric
    metric_vars = [i for i in tf.local_variables() if 'auc_roc' in i.name.split('/')[1]]

    # Add metric variables to GLOBAL_VARIABLES collection.
    # They will be initialized for new session.
    for v in metric_vars:
        tf.add_to_collection(tf.GraphKeys.GLOBAL_VARIABLES, v)

    # force to update metric values
    with tf.control_dependencies([update_op]):
        value = tf.identity(value)
        return value

# generation a small dataset
N_all = 10000
N_tr = int(0.7 * N_all)
N_te = N_all - N_tr
X, y = make_classification(n_samples=N_all, n_features=20, n_classes=2)
y = np_utils.to_categorical(y, num_classes=2)

X_train, X_valid = X[:N_tr, :], X[N_tr:, :]
y_train, y_valid = y[:N_tr, :], y[N_tr:, :]

# model & train
model = Sequential()
model.add(Dense(2, activation="softmax", input_shape=(X.shape[1],)))

model.compile(loss='categorical_crossentropy',
              optimizer='adam',
              metrics=['accuracy', auc_roc])

my_callbacks = [EarlyStopping(monitor='auc_roc', patience=300, verbose=1, mode='max')]

model.fit(X, y,
          validation_split=0.3,
          shuffle=True,
          batch_size=32, nb_epoch=5, verbose=1,
          callbacks=my_callbacks)

# # or use independent valid set
# model.fit(X_train, y_train,
#           validation_data=(X_valid, y_valid),
#           batch_size=32, nb_epoch=5, verbose=1,
#           callbacks=my_callbacks)
27
répondu Tom 2018-05-15 02:37:20

j'ai résolu mon problème de cette façon

considérez que vous avez jeu de données de test x_test pour les fonctions et les y_test pour ses cibles correspondantes.

tout d'abord, nous prédisons les cibles à partir de la fonctionnalité en utilisant notre modèle formé

 y_pred = model.predict_proba(x_test)

puis de sklearn nous importons roc_auc_score fonction et puis simple passer les cibles originales et prédites cibles à la fonction.

 roc_auc_score(y_test, y_pred)
9
répondu Eka 2017-02-28 16:51:41

'roc_curve', ' auc ' ne sont pas des mesures standard vous ne pouvez pas les passer comme ça à la variable metrics, ce n'est pas autorisé. Vous pouvez passer quelque chose comme' fmeasure ' qui est une métrique standard.

Revue les données disponibles ici: https://keras.io/metrics/ Vous pouvez également jeter un coup d'oeil à la fabrication de votre propre métrique personnalisée:https://keras.io/metrics/#custom-metrics

regarder generate_results méthode mentionnée dans ce blog pour ROC, AUC... https://vkolachalama.blogspot.in/2016/05/keras-implementation-of-mlp-neural.html

6
répondu sunil manikani 2016-12-15 07:03:19

Vous pouvez envelopper tf.métriques (par exemple,tf.metrics.auc) en kéras.métrique.

à Partir de ma réponse comment utiliser les mesures TensorFlow dans Keras:

def as_keras_metric(method):
    import functools
    from keras import backend as K
    import tensorflow as tf
    @functools.wraps(method)
    def wrapper(self, args, **kwargs):
        """ Wrapper for turning tensorflow metrics into keras metrics """
        value, update_op = method(self, args, **kwargs)
        K.get_session().run(tf.local_variables_initializer())
        with tf.control_dependencies([update_op]):
            value = tf.identity(value)
        return value
    return wrapper

usage de base:

auc_roc = as_keras_metric(tf.metrics.auc)
recall = as_keras_metric(tf.metrics.recall)
...

compilez le modèle keras:

model.compile(..., metrics=[auc_roc])
6
répondu Christian Skjødt 2018-05-25 10:50:38

La solution suivante a fonctionné pour moi:

import tensorflow as tf
from keras import backend as K

def auc(y_true, y_pred):
    auc = tf.metrics.auc(y_true, y_pred)[1]
    K.get_session().run(tf.local_variables_initializer())
    return auc

model.compile(loss="binary_crossentropy", optimizer='adam', metrics=[auc])
2
répondu B. Kanani 2018-07-22 15:01:59

comme vous, je préfère utiliser les méthodes intégrées de scikit-learn pour évaluer AUROC. Je trouve que la meilleure et la plus facile façon de le faire dans keras est de créer une métrique personnalisée. Si tensorflow est votre backend, implémenter ceci peut être fait en très peu de lignes de code:

import tensorflow as tf
from sklearn.metrics import roc_auc_score

def auroc(y_true, y_pred):
    return tf.py_func(roc_auc_score, (y_true, y_pred), tf.double)

# Build Model...

model.compile(loss='categorical_crossentropy', optimizer='adam',metrics=['accuracy', auroc])

créer un Callback personnalisé tel que mentionné dans d'autres réponses ne fonctionnera pas pour votre cas puisque votre modèle a plusieurs ouputs, mais cela fonctionnera. En outre, cette méthode permet d'évaluer la métrique à la fois données de formation et de validation alors qu'un appel keras n'a pas accès aux données de formation et ne peut donc être utilisé que pour évaluer la performance sur les données de formation.

1
répondu Kimball Hill 2018-08-07 20:42:03