使用 Keras flow_from_directory 获取混淆矩阵

数据挖掘 机器学习 Python 美国有线电视新闻网
2022-03-06 17:22:04

对于家庭作业,我必须分析一组图像。为此,我计划使用卷积神经网络。图像被拆分到特定文件夹:

  • 包含 624 张照片的测试集
    • 数据集/测试/正常(234 项)
    • 数据集/测试/肺炎(390 项)
  • 5216张照片的火车套装
    • 数据集/训练/正常(1341 项)
    • 数据集/火车/肺炎(3875 项)

目标是学习一台机器来检测某人是否患有肺炎。

为此,我尝试构建一个卷积神经网络并获得相当不错的结果:

  • 损失:0.0328
  • 准确度:0.9877
  • val_loss:0.2308
  • val_accuracy:0.9231

在此处输入图像描述

# Artificial Neural Network - Convolutional Neural Network

# Building the CNN
# Importing keras libraries and packages
import sys
from matplotlib import pyplot as plt
import numpy as np

from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers import Dense

from sklearn.metrics import classification_report as cr
from sklearn.metrics import confusion_matrix as cm

# defining variables
# Start
train_data_path = 'dataset/train'
test_data_path = 'dataset/test'
val_data_path = 'dataset/val'

img_rows = 64
img_cols = 64
epochs = 5
batch_size = 32
num_of_train_samples = 5216
num_of_test_samples = 624

# plot diagnostic learning curves
def summarize_diagnostics(history):
    # plot loss
    plt.subplot(211)
    plt.title('Cross Entropy Loss')
    plt.plot(history.history['loss'], color='blue', label='train')
    plt.plot(history.history['val_loss'], color='orange', label='test')
    # plot accuracy
    plt.subplot(212)
    plt.title('Classification Accuracy')
    plt.plot(history.history['accuracy'], color='blue', label='train')
    plt.plot(history.history['val_accuracy'], color='orange', label='test')
    # save plot to file
    filename = sys.argv[0].split('/')[-1]
    plt.savefig(filename + '_plot.png')
    plt.close()

# Initialising the CNN - Building the model
classifier = Sequential()
# Step 1 : Convolution (test with 64) & ReLU
classifier.add(Conv2D(32, (3, 3), 
                      input_shape=(img_rows, img_cols, 3), 
                      activation='relu')
    )
# Step 2 : Max Pooling
classifier.add(MaxPooling2D(pool_size=(2,2)))
classifier.add(Dropout(0.1))

# Step 2b - enhancing accuracy : adding convolution layers
classifier.add(Conv2D(32, (3, 3), activation='relu'))
classifier.add(MaxPooling2D(pool_size=(2,2)))
classifier.add(Dropout(0.1))

classifier.add(Conv2D(64, (3, 3), activation='softmax'))
classifier.add(MaxPooling2D(pool_size=(2,2)))
classifier.add(Dropout(0.3))

# Step 3 : Flattening
classifier.add(Flatten())

# Step 4 : Full connection (hidden layer)
classifier.add(Dense(units=128, activation='relu'))
# enhancing accuracy : adding a layer 
classifier.add(Dense(units=128, activation='relu'))

classifier.add(Dense(units=1, activation='sigmoid'))

# Compiling the CNN
classifier.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

# Part 2 : Fitting the CNN to the images
# https://keras.io/preprocessing/image/#imagedatagenerator-class
from keras.preprocessing.image import ImageDataGenerator

train_datagen = ImageDataGenerator(
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)

test_datagen = ImageDataGenerator(rescale=1./255)

# increase image size to enhance results
training_set = train_datagen.flow_from_directory(
        'dataset/train',
        target_size=(64, 64),
        batch_size=64,
        class_mode='binary')

test_set = test_datagen.flow_from_directory(
        'dataset/test',
        target_size=(64, 64),
        batch_size=64,
        class_mode='binary')

history = classifier.fit_generator(
        training_set,
        steps_per_epoch=5216,
        epochs=5,
        validation_data=test_set,
        validation_steps=624)

# evaluate model
_, acc = classifier.evaluate_generator(test_set, steps=len(test_set), verbose=0)
print('> %.3f' % (acc * 100.0))

summarize_diagnostics(history)

我想建立混淆矩阵并知道训练集中有多少图像。它会让我得到假阳性和假阴性结果。

为此,我编写了这段代码:

#Confution Matrix and Classification Report
Y_pred = classifier.predict_generator(training_set, 624 // batch_size+1)
y_pred = np.argmax(Y_pred, axis=1)
print('Confusion Matrix')
matrix = cm(training_set.classes, y_pred)
print(matrix)
print('Classification Report')

print(cr(training_set.classes, y_pred))

在运行这些行时:

我没有得到矩阵变量并获得错误消息:

ValueError:发现样本数量不一致的输入变量:[5216, 1280]

我不确定我是否正确设置了混淆矩阵。谢谢。

1个回答

这与您输入cm函数的不同形状有关。您正在传递training_set.classes(将具有 length n_classes)和y_pred(将具有 length n_samples)。因此,您应该传递每个样本的真实标签,而不是传递training_set.classes,以便该向量的长度也为n_samples.