我正在为二进制图像分类构建一个简单的CNN,并且从model.evaluate()获得的 AUC远高于从model.predict()+ roc_auc_score()获得的AUC。。 >
整个笔记本是here。
为model.fit()编译模型和输出:
model.compile(loss='binary_crossentropy',
optimizer=RMSprop(lr=0.001),
metrics=['AUC'])
history = model.fit(
train_generator,
steps_per_epoch=8,
epochs=5,
verbose=1)
第1/5集 8/8 [=============================]-21s 3s / step-损失:6.7315-auc:0.5143 >
第2/5集 8/8 [=============================]-15s 2s / step-损失:0.6626-auc:0.6983 >
第3/5集 8/8 [=============================]-18s 2s / step-损耗:0.4296-auc:0.8777 >
第4/5集 8/8 [=============================]-14s 2s / step-损失:0.2330-auc:0.9606 >
史诗5/5 8/8 [=============================]-18s 2s / step-损失:0.1985-auc:0.9767 >
然后model.evaluate()提供类似的内容:
model.evaluate(train_generator)
9/9 [==============================]-10s 1s / step-损失:0.3056-auc: 0.9956
但是直接从model.predict()方法计算出的AUC降低了两倍:
from sklearn import metrics
x = model.predict(train_generator)
metrics.roc_auc_score(train_generator.labels, x)
0.5006148007590132
我已经阅读了有关类似问题的几篇文章(例如this,this,this以及extensive discussion on github),但它们描述了与我的情况无关的原因:
任何建议都将不胜感激。谢谢!
编辑!解决方案 我已经建立了解决方案here,我只需要打电话
train_generator.reset()
在model.predict之前,并在flow_from_directory()函数中设置shuffle = False。产生差异的原因是,生成器从不同的位置开始输出批次,因此标签和预测将不匹配,因为它们与不同的对象相关。因此,问题不在于评估或预测方法,而在于生成器。
编辑2 如果使用flow_from_directory()创建生成器,则使用train_generator.reset()并不方便,因为它需要在flow_from_directory中设置shuffle = False,但这会在训练期间创建包含单个类的批处理,这会影响学习。因此,在运行预测之前,我最终重新定义了train_generator。
答案 0 :(得分:1)
tensorflow.keras
AUC通过Riemann和计算近似AUC(曲线下的面积),这与scikit-learn的实现方式不同。
如果要使用tensorflow.keras
查找AUC,请尝试:
import tensorflow as tf
m = tf.keras.metrics.AUC()
m.update_state(train_generator.labels, x) # assuming both have shape (N,)
r = m.result().numpy()
print(r)