tensorflow model.evaluate 和 model.predict 非常不同的结果

Posted

技术标签:

【中文标题】tensorflow model.evaluate 和 model.predict 非常不同的结果【英文标题】:tensorflow model.evaluate and model.predict very different results 【发布时间】:2020-09-06 00:39:15 【问题描述】:

我正在构建一个简单的 CNN 用于二值图像分类,从 model.evaluate() 获得的 AUC 远高于从 model.predict() + roc_auc_score() 获得的 AUC。 p>

整个笔记本是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 - loss: 6.7315 - auc: 0.5143

纪元 2/5 8/8 [==============================] - 15s 2s/step - loss: 0.6626 - auc: 0.6983

纪元 3/5 8/8 [==============================] - 18s 2s/step - loss: 0.4296 - auc: 0.8777

4/5 纪元 8/8 [==============================] - 14s 2s/step - loss: 0.2330 - auc: 0.9606

5/5 纪元 8/8 [==============================] - 18s 2s/step - loss: 0.1985 - auc: 0.9767

然后 model.evaluate() 给出类似的结果:

model.evaluate(train_generator)

9/9 [==============================] - 10s 1s/step - loss: 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),但它们描述的原因与我的情况无关:

将 binary_crossenthropy 用于多类任务(不是我的情况) 由于使用批量与整体,评估和预测之间的差异 数据集(不应该像我的情况那样导致急剧下降) 使用批量标准化和正则化(不是我的情况,也应该 不会造成如此大的下降)

非常感谢任何建议。谢谢!


编辑!解决方案 我已经创建了解决方案here,我只需要打电话

train_generator.reset()

在 model.predict 之前并在 flow_from_directory() 函数中设置 shuffle = False。差异的原因是生成器从不同的位置开始输出批次,因此标签和预测将不匹配,因为它们与不同的对象相关。所以问题不在于评估或预测方法,而在于生成器。


编辑 2 如果使用 flow_from_directory() 创建生成器,则使用 train_generator.reset() 不方便,因为它需要在 flow_from_directory 中设置 shuffle = False,但这会在训练期间创建包含单个类的批次,从而影响学习。所以我最终在运行 predict 之前重新定义了 train_generator。

【问题讨论】:

【参考方案1】:

tensorflow.keras AUC 通过黎曼和计算近似 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)

【讨论】:

感谢您的建议!不幸的是,这并没有帮助 - 使用您的解决方案获得的结果与 model.predict 非常相似,也远低于 model.evaluate(请参阅文件末尾的here)。我也认为不同实现中计算的差异可能会导致细微的差异,但不是 0.9 vs 0.5。 你能添加train_generator.labels和x的形状吗?还有前几个值? 当然,请参阅here(再次在文件末尾)

以上是关于tensorflow model.evaluate 和 model.predict 非常不同的结果的主要内容,如果未能解决你的问题,请参考以下文章

Tensorflow model.evaluate 给出的结果与从训练中获得的结果不同

model.evaluate() 和 model.predict() 的 F1 不同

Keras model.evaluate() 和 model.predict() 有啥区别?

Keras 中的 model.evaluate() 返回啥值?

Keras model.evaluate_generator结果几乎是真实准确度的两倍?

Keras:训练和验证集上的 model.evaluate() 与上次训练时期后的 acc 和 val_acc 不同