我正在构建一个用于二值图像分类的简单CNN,以及从模型中获得的AUC。evaluate()远高于从模型中获得的AUC。预测()roc\U auc\U分数()。
整个笔记本都在这里。
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[======================================================]21秒/步长-损耗:6.7315-auc:0.5143
纪元2/5 8/8 [==============================] - 15s 2s/阶跃损失: 0.6626-auc: 0.6983
纪元3/5 8/8[===================================================]18秒/步-损耗:0.4296-auc:0.8777
纪元4/5 8/8[=========================================================-14s 2s/步-损耗:0.2330-auc:0.9606
纪元5/5 8/8[===================================================]18秒/步-损失:0.1985-auc:0.9767
然后是模型。evaluate()给出了类似的结果:
model.evaluate(train_generator)
9/9[=======================================]-10s 1s/步-损耗: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
我读过几篇关于类似问题的帖子(比如这个,这个,这个,还有关于github的广泛讨论),但它们描述了与我的案例无关的原因:
任何建议都非常感谢。谢谢!
编辑解决方案我在这里找到了解决方案,我只需要打电话
train_generator.reset()
在model.predict之前,还在flow_from_directory()函数中设置Shuffle=False。差异的原因是生成器从不同的位置开始输出批次,因此标签和预测将不匹配,因为它们涉及不同的对象。所以问题不在于评估或预测方法,而在于生成器。
使用序列生成器编辑2。如果生成器是使用来自目录()的flow_创建的,则reset()不方便,因为它需要在来自目录()的flow_中设置shuffle=False,但这将在培训期间创建包含单个类的批处理,从而影响学习。因此,在运行predict之前,我重新定义了train_生成器。
tensorflow。keras
AUC通过黎曼和计算近似AUC(曲线下面积),这与scikit学习不同。
如果要使用tensorflow查找AUC。keras
,请尝试:
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)