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?
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)
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)
'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
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])
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])
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.