Sklearn clearly defines how to plot a confusion matrix using its own classification model with plot_confusion_matrix
.
But what about using it with Keras model using data generators? Let’s have a look at an example code:
First we need to train the model.
import numpy as np from keras import backend as K from keras.models import Sequential from keras.layers.core import Dense, Dropout, Activation, Flatten from keras.layers.convolutional import Convolution2D, MaxPooling2D from keras.preprocessing.image import ImageDataGenerator from sklearn.metrics import classification_report, confusion_matrix #Start train_data_path = 'F://data//Train' test_data_path = 'F://data//Validation' img_rows = 150 img_cols = 150 epochs = 30 batch_size = 32 num_of_train_samples = 3000 num_of_test_samples = 600 #Image Generator train_datagen = ImageDataGenerator(rescale=1. / 255, rotation_range=40, width_shift_range=0.2, height_shift_range=0.2, shear_range=0.2, zoom_range=0.2, horizontal_flip=True, fill_mode='nearest') test_datagen = ImageDataGenerator(rescale=1. / 255) train_generator = train_datagen.flow_from_directory(train_data_path, target_size=(img_rows, img_cols), batch_size=batch_size, class_mode='categorical') validation_generator = test_datagen.flow_from_directory(test_data_path, target_size=(img_rows, img_cols), batch_size=batch_size, class_mode='categorical') # Build model model = Sequential() model.add(Convolution2D(32, (3, 3), input_shape=(img_rows, img_cols, 3), padding='valid')) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Convolution2D(32, (3, 3), padding='valid')) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Convolution2D(64, (3, 3), padding='valid')) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Flatten()) model.add(Dense(64)) model.add(Activation('relu')) model.add(Dropout(0.5)) model.add(Dense(5)) model.add(Activation('softmax')) model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy']) #Train model.fit_generator(train_generator, steps_per_epoch=num_of_train_samples // batch_size, epochs=epochs, validation_data=validation_generator, validation_steps=num_of_test_samples // batch_size)
Now after the model is trained let’s build a confusion matrix.
#Confution Matrix and Classification Report Y_pred = model.predict_generator(validation_generator, num_of_test_samples // batch_size+1) y_pred = np.argmax(Y_pred, axis=1) print('Confusion Matrix') print(confusion_matrix(validation_generator.classes, y_pred)) print('Classification Report') target_names = ['Cats', 'Dogs', 'Horse'] print(classification_report(validation_generator.classes, y_pred, target_names=target_names))
Now this works fine so far. But how do I save it as png in the same layout as in the above sklearn example?
Advertisement
Answer
Like this (also see ConfusionMatrixDisplay
and confusion_matrix
):
from sklearn.metrics import ConfusionMatrixDisplay from sklearn.metrics import confusion_matrix import matplotlib.pyplot as plt import numpy as np y_pred = np.array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2]) y_test = np.array([0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 2]) labels = ["Cats", "Dogs", "Horses"] cm = confusion_matrix(y_test, y_pred) disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=labels) disp.plot(cmap=plt.cm.Blues) plt.show()
Result: