63 votes

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?

67voto

Tom Points 1245

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))])
 

Une méthode plus piratable 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)
 

39voto

Kimball Hill Points 71

Comme vous, je préfère utiliser scikit-learn construit dans les méthodes pour évaluer l'AUROC. Je trouve que la plus simple et la meilleure façon de le faire dans keras est de créer un personnalisé métrique. Si tensorflow est votre arrière-plan, la mise en œuvre de ce qui 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])

La création d'une fonction de Rappel personnalisée comme mentionné dans d'autres réponses ne fonctionnera pas pour votre cas puisque votre modèle a plusieurs ouputs, mais cela fonctionne. En outre, cette méthode permet à la métrique et à apprécier à la fois la formation et la validation des données alors qu'un keras de rappel n'ont pas accès à des données de formation et peut uniquement être utilisé pour évaluer les performances sur les données d'apprentissage.

23voto

B. Kanani Points 318

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])
 

15voto

Eka Points 511

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 caractéristiques et les y_test pour ses cibles correspondantes.

nous avons d'abord prévoir des objectifs de fonctionnalité à l'aide de notre modèle appris

 y_pred = model.predict_proba(x_test)

puis, à partir de sklearn nous importons roc_auc_score fonction et alors simple passer les objectifs initiaux et les cibles prévues pour la fonction.

 roc_auc_score(y_test, y_pred)

6voto

sunil manikani Points 181

'roc_curve','asc' ne sont pas les paramètres standard, vous ne pouvez pas passer comme ça à métrique variable, ce n'est pas autorisé. Vous pouvez passer à quelque chose comme "fmeasure", qui est une mesure standard.

Examiner les données disponibles ici: https://keras.io/metrics/ Vous pouvez également avoir un coup d'oeil à vous de faire vos propres mesures personnalisées: https://keras.io/metrics/#custom-metrics

Aussi jeter un oeil à generate_results méthode mentionnée dans ce blog pour le rdc, AUC... https://vkolachalama.blogspot.in/2016/05/keras-implementation-of-mlp-neural.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X