web-dev-qa-db-fra.com

Comment calculer la caractéristique de fonctionnement de réception (ROC) et l'ASC dans les keras?

J'ai un modèle de classification binaire à sorties multiples (200) que j'ai écrit en keras.

Dans ce modèle, je souhaite ajouter des mesures supplémentaires telles que le ROC et l'AUC, mais à ma connaissance, les keras n'ont pas de fonctions de métrique ROC et AUC intégrées.

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 ça donne cette erreur:

Exception: métrique non valide: roc_curve

Comment dois-je ajouter ROC, AUC à keras?

44
Eka

En raison de cela, vous ne pouvez pas calculer le RDC & l'AUC par mini-lots, vous ne pouvez le calculer qu'à la fin d'une époque. Il existe une solution de jamartinh , je corrige les codes ci-dessous pour plus de 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))])

Un moyen plus piratable 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)
57
Tom

Comme vous, je préfère utiliser les méthodes intégrées de scikit-learn pour évaluer AUROC. Je trouve que le meilleur moyen de le faire dans keras est de créer une métrique personnalisée. Si tensorflow est votre backend, l'implémentation peut être faite 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])

La création d'un rappel personnalisé, comme indiqué dans d'autres réponses, ne fonctionnera pas pour votre cas, car votre modèle dispose de plusieurs sorties, mais cela fonctionnera. De plus, cette méthode permet d'évaluer la métrique à la fois sur les données d'apprentissage et de validation, alors qu'un callback keras n'a pas accès aux données d'apprentissage et ne peut donc être utilisé que pour évaluer les performances des données d'apprentissage.

28
Kimball Hill

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])
20
B. Kanani

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

considérez que vous avez un ensemble de données de test x_test pour les entités et y_test pour ses cibles correspondantes .

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

 y_pred = model.predict_proba(x_test)

puis, à partir de sklearn, nous importons roc_auc_score fonction, puis passons simplement les cibles d'origine et les cibles prédites à la fonction.

 roc_auc_score(y_test, y_pred)
15
Eka

'roc_curve', 'auc' ne sont pas des métriques standard, vous ne pouvez pas les transmettre comme ça à une variable de métrique, ceci n'est pas autorisé. Vous pouvez passer quelque chose comme "mesure" qui est une métrique standard.

Passez en revue les métriques disponibles ici: https://keras.io/metrics/ Vous pouvez également essayer de créer votre propre métrique personnalisée: https://keras.io/ métriques/# métriques personnalisées

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

6
sunil manikani

En ajoutant aux réponses ci-dessus, j'ai eu l'erreur "ValueError: mauvaise forme d'entrée ...", donc je spécifie le vecteur de probabilités comme suit:

y_pred = model.predict_proba(x_test)[:,1]
auc = roc_auc_score(y_test, y_pred)
print(auc)
1
KarthikS