Как вычислить получение эксплуатационных характеристик (ROC) и AUC в keras?

У меня есть модель множественного вывода (200), которую я написал в keras.

В этой модели я хочу добавить дополнительные показатели, такие как ROC и AUC, но, насколько мне известно, keras dosen't имеют встроенные метрические функции ROC и AUC.

Я пытался импортировать ROC, AUC функции из 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'])

но он дает эту ошибку:

Исключение: неверная метрика: roc_curve

Как мне добавить ROC, AUC в keras?

Ответ 1

Из-за того, что вы не можете рассчитать ROC & AUC по мини-пакетам, вы можете рассчитать его только в конце одной эпохи. Есть решение от jamartinh, я для удобства прошиваю приведенные ниже коды:

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

Более взломанный способ с использованием 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)

Ответ 2

Следующее решение работало для меня:

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

Ответ 3

Как и вы, я предпочитаю использовать встроенные методы scikit-learn для оценки AUROC. Я считаю, что лучший и самый простой способ сделать это в керасе - это создать собственную метрику. Если тензор потока является вашим бэкэндом, реализация этого может быть осуществлена в несколько строк кода:

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

Создание пользовательского обратного вызова, как упоминалось в других ответах, не будет работать для вашего случая, так как ваша модель имеет несколько выходов, но это будет работать. Кроме того, этот метод позволяет оценивать метрику как по данным обучения, так и по проверке, тогда как обратный вызов keras не имеет доступа к данным обучения и, таким образом, может использоваться только для оценки эффективности данных обучения.

Ответ 4

Я решил проблему таким образом

рассмотрим, что у вас есть тестовый набор данных x_test для функций и y_test для соответствующих целей.

сначала мы прогнозируем цели из функции с помощью нашей обучаемой модели

 y_pred = model.predict_proba(x_test)

то из sklearn мы импортируем функцию roc_auc_score, а затем просто передаем исходные цели и предсказанные цели функции.

 roc_auc_score(y_test, y_pred)

Ответ 5

'roc_curve', 'auc' не являются стандартными метриками, которые вы не можете передать им как переменную метрики, это недопустимо. Вы можете передать что-то вроде "fmeasure", которое является стандартной метрикой.

Просмотрите доступные показатели здесь: https://keras.io/metrics/ Вы также можете взглянуть на создание собственной собственной метрики: https://keras.io/metrics/#custom-metrics

Также посмотрите на метод generate_results, упомянутый в этом блоге для ROC, AUC... https://vkolachalama.blogspot.in/2016/05/keras-implementation-of-mlp-neural.html

Ответ 6

Добавляя ответы выше, я получил ошибку "ValueError: неправильная форма ввода...", поэтому я определяю вектор вероятностей следующим образом:

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