如何计算keras中的接收操作特性(ROC)和AUC?

时间:2016-12-08 05:44:46

标签: python theano keras

我有一个多输出(200)二进制分类模型,我在keras中写道。

在这个模型中,我想添加其他指标,如ROC和AUC,但据我所知,keras dosen没有内置的ROC和AUC指标函数。

我尝试从scikit-learn

导入ROC,AUC功能
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?

8 个答案:

答案 0 :(得分:50)

由于您无法通过小批量计算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)

答案 1 :(得分:18)

以下解决方案对我有用:

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 :(得分:17)

像您一样,我更喜欢使用scikit-learn的内置方法来评估AUROC。我发现在keras中执行此操作的最佳和最简单的方法是创建自定义指标。如果tensorflow是您的后端,则可以用很少的几行代码来实现:

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回调无法访问训练数据,因此只能用于评估训练数据的性能。

答案 3 :(得分:14)

我用这种方式解决了我的问题

考虑您为功能测试数据集 x_test ,为相应的目标测试 y_test

首先,我们使用训练模型预测特征中的目标

 y_pred = model.predict_proba(x_test)

然后从sklearn我们导入roc_auc_score函数,然后简单地将原始目标和预测目标传递给函数。

 roc_auc_score(y_test, y_pred)

答案 4 :(得分:10)

您可以通过以下方式提供指标来监控培训期间的auc:

METRICS = [
      keras.metrics.TruePositives(name='tp'),
      keras.metrics.FalsePositives(name='fp'),
      keras.metrics.TrueNegatives(name='tn'),
      keras.metrics.FalseNegatives(name='fn'), 
      keras.metrics.BinaryAccuracy(name='accuracy'),
      keras.metrics.Precision(name='precision'),
      keras.metrics.Recall(name='recall'),
      keras.metrics.AUC(name='auc'),
]


model = keras.Sequential([
    keras.layers.Dense(16, activation='relu', input_shape=(train_features.shape[-1],)),
    keras.layers.Dense(1, activation='sigmoid'),
  ])

model.compile(
    optimizer=keras.optimizers.Adam(lr=1e-3)
    loss=keras.losses.BinaryCrossentropy(),
    metrics=METRICS)

有关更详细的教程,请参见:
https://www.tensorflow.org/tutorials/structured_data/imbalanced_data

答案 5 :(得分:6)

'roc_curve','auc'不是标准指标,你不能将它们传递给指标变量,这是不允许的。 你可以传递像'fmeasure'这样的标准指标。

在此处查看可用指标:https://keras.io/metrics/ 您可能还想了解制作自己的自定义指标:https://keras.io/metrics/#custom-metrics

另请参阅本博客中提到的针对ROC,AUC的generate_results方法... https://vkolachalama.blogspot.in/2016/05/keras-implementation-of-mlp-neural.html

答案 6 :(得分:0)

除了上述答案外,我还收到错误“ ValueError:输入形状错误...”,因此我按如下方式指定了概率向量:

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

答案 7 :(得分:0)

使用tf.keras.metrics.AUC()设置模型架构: 阅读以下Keras博客:Keras Page

paste0("MAP_", trimws(tt, whitespace = ".*_"))
#[1] "MAP_62770" "MAP_6272"  "MAP_1222"