为图像分类模型绘制混淆矩阵

Posted

技术标签:

【中文标题】为图像分类模型绘制混淆矩阵【英文标题】:plotting confusion matrix for an image classification model 【发布时间】:2018-12-19 07:05:08 【问题描述】:

我用 keras 构建了一个图像分类 CNN。虽然模型本身工作正常(它可以正确预测新数据),但我在绘制模型的混淆矩阵和分类报告时遇到了问题。

我使用 ImageDataGenerator 训练了模型

train_path = '../DATASET/TRAIN'
test_path = '../DATASET/TEST'
IMG_BREDTH = 30
IMG_HEIGHT = 60
num_classes = 2

train_batch = ImageDataGenerator(featurewise_center=False,
                                 samplewise_center=False, 
                                 featurewise_std_normalization=False, 
                                 samplewise_std_normalization=False, 
                                 zca_whitening=False, 
                                 rotation_range=45, 
                                 width_shift_range=0.2, 
                                 height_shift_range=0.2, 
                                 horizontal_flip=True, 
                                 vertical_flip=False).flow_from_directory(train_path, 
                                                                          target_size=(IMG_HEIGHT, IMG_BREDTH), 
                                                                          classes=['O', 'R'], 
                                                                          batch_size=100)

test_batch = ImageDataGenerator().flow_from_directory(test_path, 
                                                      target_size=(IMG_HEIGHT, IMG_BREDTH), 
                                                      classes=['O', 'R'], 
                                                      batch_size=100)

这是混淆矩阵和分类报告的代码

batch_size = 100
target_names = ['O', 'R']
Y_pred = model.predict_generator(test_batch, 2513 // batch_size+1)
y_pred = np.argmax(Y_pred, axis=1)
print('Confusion Matrix')
cm = metrics.confusion_matrix(test_batch.classes, y_pred)
print(cm)
print('Classification Report')
print(metrics.classification_report(test_batch.classes, y_pred))

对于混淆矩阵,我得到滚动结果(这似乎是错误的)

Confusion Matrix
[[1401    0]
 [1112    0]]

假阳性和真阳性均为 0。 对于分类报告,我得到以下输出和警告

Classification Report
             precision    recall  f1-score   support

          0       0.56      1.00      0.72      1401
          1       0.00      0.00      0.00      1112

avg / total       0.31      0.56      0.40      2513

/Users/sashaanksekar/anaconda3/lib/python3.6/site-packages/sklearn/metrics/classification.py:1135: UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples.
  'precision', 'predicted', average, warn_for)

我试图预测一个物体是有机的还是可回收的。我有大约 22000 张训练图像和 2513 张测试图像。

我是机器学习的新手。我究竟做错了什么?

提前致谢

【问题讨论】:

问题/错误是什么? 混淆矩阵的真阳性和假阳性为0。我觉得这是因为我初始化y_pred的方式。我也不明白分类报告的警告信息 您需要确保在metrics.confusion_matrix() 中以正确的顺序插入y_predy_true。其次,这种糟糕的性能可能是由于过度拟合或模型不佳造成的。你使用交叉验证吗? 不,我没有。由于我是机器学习的新手,我不知道如何处理图像数据。 可以添加数据吗? 【参考方案1】:

要绘制混淆矩阵,请执行以下操作:

import matplotlib.pyplot as plt
import numpy as np

cm = metrics.confusion_matrix(test_batch.classes, y_pred)
# or
#cm = np.array([[1401,    0],[1112, 0]])

plt.imshow(cm, cmap=plt.cm.Blues)
plt.xlabel("Predicted labels")
plt.ylabel("True labels")
plt.xticks([], [])
plt.yticks([], [])
plt.title('Confusion matrix ')
plt.colorbar()
plt.show()

参考文献:

https://www.dataschool.io/simple-guide-to-confusion-matrix-terminology/

https://machinelearningmastery.com/confusion-matrix-machine-learning/

【讨论】:

我应该如何解释混淆矩阵? 你好。混淆矩阵同时显示了很多东西。首先,黑色块在对角线上时性能更高。在这里,您非常擅长预测一个类,但非常不擅长预测另一类。此外,从混淆矩阵中,您可以计算灵敏度、特异性、假阳性率、假阴性率等......我将在我的答案中添加一些关于 CM 的参考 我觉得我的 y_pred 初始化错误。如何初始化 y_pred? y_pred 是测试数据的预测标签。在model.predict_generator之前,您是否使用训练数据拟合模型? 我使用 fit_generator 来训练网络。当我使用 predict 函数对新数据进行预测时,该模型大部分时间都能正常工作。所以混淆矩阵中的TP不应该是0。【参考方案2】:

如果有人像我一样因为类似的问题来到这里,可能有几件事可以提供帮助:

    确保在测试集生成器中设置shuffle = False; 最好将batch_size 设置为图像计数的除数。如果没有 - 确保生成器不会跳过任何图像; 先尝试不进行增强的训练;

    predict_generator 的输出似乎不一致,如果可能,请尝试设置workers = 0,如下所示:

    predictions = model.predict_generator(testGenerator, steps = np.ceil(testGenerator.samples / testGenerator.batch_size), verbose=1, workers=0)

在我的情况下,如果我不这样做,每次我打电话给 predict_generator 时,预测都会改变。

    当你只有两个类时,你必须使用:

    predictedClasses = np.where(predictions>0.5, 1, 0) 而不是np.argmax(Y_pred, axis=1),因为在这种情况下np.argmax 将始终输出0。

    np.where(predictions>0.5, 1, 0) 如果预测 > 0.5 则返回 1,否则返回 0。

【讨论】:

【参考方案3】:

我使用 sklearn plot_confusion_matrix

为了使用它,我做了一个 hack,所以当 sklearn 估计器进行预测时不要抱怨,因为它是 Keras 模型。 因此,如果模型是经过训练的 keras 模型:

X,y = test_generator.next()
y = np.argmax(y, axis=1)

from sklearn.metrics import plot_confusion_matrix
class newmodel(MLPClassifier):
    def __init__(self, model):
        self.model = model
    def predict(self, X):
        y = self.model.predict(X)
        return np.argmax(y,axis=1)

model1 = newmodel(model)
plot_confusion_matrix(model1, X, y , normalize='true', xticks_rotation = 'vertical', display_labels = list(train_generator.class_indices.keys()))

它对我有用。

【讨论】:

以上是关于为图像分类模型绘制混淆矩阵的主要内容,如果未能解决你的问题,请参考以下文章

Python遥感图像处理应用篇(二十八):Python绘制遥感图像分类结果混淆矩阵和计算分类精度

Python遥感图像处理应用篇(二十八):Python绘制遥感图像分类结果混淆矩阵和计算分类精度

第七篇 图像分类的评价指标

遥感软件中混淆矩阵是如何产生的

混淆矩阵-MATLAB代码详解

如何在 Tensorflow 中为预取数据集绘制混淆矩阵