Keras, дополнительный набор проверки во время обучения не совпадает с sklearn auc - PullRequest
0 голосов
/ 07 сентября 2018

Я использую свой тестовый набор в качестве набора проверки.Я использовал такой же подход, как Как вычислить Receiving Operating Characteristic (ROC) и AUC в кератах?

Проблема в том, что мой val_auc во время обучения составляет около 0,85, как всегда, когда я использую

fpr, tpr, _ = roc_curve(test_label, test_prediction)
roc_auc = auc(fpr, tpr)

Я получаю аук 0,60.Я понимаю, что они используют другую формулировку, а также потоковый auc может отличаться от того, который рассчитывает sklearn.однако разница очень большая, и я не могу понять, что является причиной этой разницы.

# 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

clf = Sequential()

clf.add(LSTM(units = 128, input_shape = (windowlength, trainX.shape[2]), return_sequences = True))#, kernel_regularizer=regularizers.l2(0.01)))

clf.add(Dropout(0.2))

clf.add(LSTM(units = 64, return_sequences = False))#, kernel_regularizer=regularizers.l2(0.01)))

clf.add(Dropout(0.2))

clf.add(Dense(units = 128, activation = 'relu'))
clf.add(Dropout(0.2))

clf.add(Dense(units = 128, activation = 'relu'))

clf.add(Dense(units = 1, activation = 'sigmoid'))
clf.compile(loss='binary_crossentropy', optimizer = 'adam', metrics = ['acc', auc_roc])

my_callbacks = [EarlyStopping(monitor='auc_roc', patience=50, verbose=1, mode='max')]
clf.fit(trainX, trainY, batch_size = 1000, epochs = 80, class_weight = class_weights, validation_data = (testX, testY), 
        verbose = 2, callbacks=my_callbacks)
y_pred_pro = model.predict_proba(testX)
print (roc_auc_score(y_test, y_pred_pro))

Я действительно ценю, если кто-нибудь может направить меня в правильном направлении.

1 Ответ

0 голосов
/ 09 сентября 2018

Прежде всего, tf.contrib.metrics.streaming_auc устарело, вместо этого используйте tf.metrics.auc.

Как вы упомянули, TF использует другой метод для вычисления AUC, чем Scikit-learn.TF использует приблизительный метод.Цитирую документацию:

Чтобы дискретизировать кривую AUC, для вычисления пар значений отзыва и точности используется линейно разнесенный набор порогов.

Это почти всегда даетболее высокая оценка AUC, чем фактическая оценка.Кроме того, для параметра thresholds по умолчанию установлено значение 200, что является низким значением, если ваш набор данных большой.Увеличение его должно сделать счет более точным, но независимо от того, насколько высоко вы его установили, всегда будет какая-то ошибка.

Scikit-learn, с другой стороны, вычисляет «истинную» оценку AUC другим методом.

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

...