【问题标题】:strongly different accuracy-values from model.evaluate(test_set) and from the sklearn classification_report来自 model.evaluate(test_set) 和 sklearn classification_report 的准确度值有很大不同
【发布时间】:2023-01-04 01:46:02
【问题描述】:

我正在用 32x32 像素的图像对图像分类中的 colab 进行实验;我有 248 张图片用于训练和 62 张用于测试(我知道太少了,但用于实验......)。只有两个类,我得到的数据如下:

train_datagen = tf.keras.preprocessing.image.ImageDataGenerator(
                rescale=1./255,
                shear_range=0.2,
                zoom_range=0.2,
                horizontal_flip=True)
training_set = train_datagen.flow_from_directory(
               'training_set', target_size=(32,32),
               class_mode='binary')

test_datagen = tf.keras.preprocessing.image.ImageDataGenerator(
                rescale=1./255)
test_set = test_datagen.flow_from_directory(
               'test_set', target_size=(32,32),
               class_mode='binary')

我实际的 cnn 架构是这样的:

cnn = tf.keras.models.Sequential([
    tf.keras.layers.Conv2D(64, 3, activation='relu', input_shape=[32,32,3]),
    tf.keras.layers.AveragePooling2D(2),
    tf.keras.layers.Conv2D(64, 3, activation='relu'),
    tf.keras.layers.AveragePooling2D(2),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dropout(0.5),   
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.Dropout(0.5),   
    tf.keras.layers.Dense(1, activation='sigmoid'),
])

和编译:

cnn.compile(optimizer='adam',loss='binary_crossentropy',
           metrics=['accuracy'])

训练:

hist = cnn.fit(x=training_set, validation_data=test_set, epochs=30)

30 个时期后,模型给出:

纪元 30/30 8/8 [================================] - 1 秒 168 毫秒/步 - 损失:0.4237 - 精度:0.8347 - val_loss : 0.5812 -val_accuracy:0.7419

我评估了测试数据:

cnn.evaluate(test_set)

这给了我:

2/2 [==============================] - 0s 80ms/step - loss: 0.5812 - accuracy: 0.7419

[0.5812247395515442, 0.7419354915618896]

这对于这么小的数据集来说很好,但是用 sklearn 的分类报告检查结果给出了一个低得多的值(这是正确的),只有 0.48 的准确度。 为了获得这个价值,我做了

predictions = cnn.predict(test_set)

我将预测中的概率值转换为 0 或 1(阈值 0.5)以获得预测标签和 将这些与分类报告中测试数据的正确标签进行比较:

from sklearn.metrics import confusion_matrix, classification_report
print(classification_report(test_labels, predicted_labels))

报告显示

              precision    recall  f1-score   support

           0       0.48      0.52      0.50        31
           1       0.48      0.45      0.47        31

    accuracy                           0.48        62
   macro avg       0.48      0.48      0.48        62
weighted avg       0.48      0.48      0.48        62

那么为什么 model.evaluate(...) 函数无法计算出正确的准确性或其他原因:这个评估函数到底计算了什么?这个数字 0.7419 是什么意思?

有人知道这个问题吗?

【问题讨论】:

    标签: python tensorflow evaluation


    【解决方案1】:

    我发现了这个问题的隐藏原因。它位于顺序获取所有 test_labels 的列表(真相)并通过运行对测试数据进行预测 模型.预测(测试集)。

    我发现方法 predict(test_set) 混淆了 test_set 的内容!

    所以我保存了测试集的标签进行预测(test_set),现在我的 classification_report 的准确性与方法 evaluate(test_set)/val_accuracy 的准确性完美匹配。

    我也对 test_set 中的每个单个对象进行了预测,并自己计算了准确度,这个准确度也与上一个 epoch 的 val_accuracy 匹配。

    顺便说一句:方法 evaluate(test_set) 也混淆了 test_set 的内容! 所以在“手动”从 test_set 中提取数据时必须非常小心

    【讨论】:

      【解决方案2】:

      您可以定义一个新的测试生成器,但这次将 shuffle 设置为 False。

      new_test_datagen = ImageDataGenerator(rescale=1./255)
      new_test_generator = test_datagen.flow_from_directory(test_dir,
                                        target_size=(150,150),
                                        shuffle = False,
                                        batch_size=32,
                                        seed=None)
      
      # Display classification report and accuracy score for softmax classifier
      from sklearn.metrics import classification_report, accuracy_score
      softmax_y_true = new_test_generator.classes
      softmax_y_pred = model.predict(new_test_generator)
      softmax_y_pred = np.array(list(map(lambda x: np.argmax(x),softmax_y_pred)))
      
      print("Accuracy: {0}".format(accuracy_score(softmax_y_true, softmax_y_pred)))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-15
        • 2015-06-13
        • 2019-08-05
        • 2021-08-20
        • 1970-01-01
        • 2020-10-14
        • 2014-02-19
        • 2023-04-08
        相关资源
        最近更新 更多