我将测试集用作验证集。我使用了与如何计算喀拉拉邦的接收运行特征(ROC)和AUC类似的方法?
问题是我在训练期间的val_auc约为0.85,但是当我使用
fpr, tpr, _ = roc_curve(test_label, test_prediction) roc_auc = auc(fpr, tpr)
我得到0.60的auc。我知道他们使用不同的公式,并且流式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))
如果有人能引导我朝正确的方向前进,我真的很感激。
首先,tf.contrib.metrics.streaming_auc
不建议使用,tf.metrics.auc
而是使用。
正如您已经提到的,TF与Scikit学习使用不同的方法来计算AUC。
TF使用近似方法。引用其文档:
为了离散化AUC曲线,使用线性间隔的一组阈值来计算成对的召回率和精度值。
这几乎总是会给出比实际分数更高的AUC分数。此外,thresholds
参数默认为200,如果您的数据集很大,则此参数较低。增大分数会使分数更准确,但是无论您将分数设置为多少,它总会有一些错误。
另一方面,Scikit-learn使用另一种方法来计算“真实” AUC分数。
我不知道为什么TF使用近似方法,但是我想是因为它的内存效率更高,速度更快。同样,尽管它高估了分数,但很有可能会保留模型的相对顺序:如果一个模型的近似AUC比另一个模型更好,那么其真实AUC(可能)也会更好。