Получение матрицы ошибок с помощью Keras flow_from_directory

Вопрос или проблема

Для домашнего задания мне нужно проанализировать набор изображений. Для этого я планирую использовать свёрточную нейронную сеть.
Изображения разделены на определенные папки:

Тестовый набор с 624 фотографиями

dataset/test/normal (234 элемента)
dataset/test/pneumonia (390 элементов)

Обучающий набор с 5216 фотографиями

dataset/train/normal (1341 элемент)
dataset/train/pneumonia (3875 элементов)

Цель состоит в том, чтобы обучить машину определять, есть ли у кого-то пневмония или нет.

Для этого я пытаюсь построить свёрточную нейронную сеть и получить достаточно хорошие результаты:

loss: 0.0328
accuracy: 0.9877
val_loss: 0.2308
val_accuracy: 0.9231

# Искусственная Нейронная Сеть – Свёрточная Нейронная Сеть

# Построение CNN
# Импортирование библиотек и пакетов keras
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

# определение переменных
# Начало
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

# график диагностических кривых обучения
def summarize_diagnostics(history):
# график потерь
plt.subplot(211)
plt.title(‘Кросс-энтропия потерь’)
plt.plot(history.history[‘loss’], color=”blue”, label=”обучение”)
plt.plot(history.history[‘val_loss’], color=”orange”, label=”тест”)
# график точности
plt.subplot(212)
plt.title(‘Точность классификации’)
plt.plot(history.history[‘accuracy’], color=”blue”, label=”обучение”)
plt.plot(history.history[‘val_accuracy’], color=”orange”, label=”тест”)
# сохранить график в файл
filename = sys.argv[0].split(“https://datascience.stackexchange.com/”)[-1]
plt.savefig(filename + ‘_plot.png’)
plt.close()

# Инициализация CNN – Создание модели
classifier = Sequential()
# Шаг 1 : Свёртка (тест с 64) & ReLU
classifier.add(Conv2D(32, (3, 3),
input_shape=(img_rows, img_cols, 3),
activation=’relu’)
)
# Шаг 2 : Максимальное объединение
classifier.add(MaxPooling2D(pool_size=(2,2)))
classifier.add(Dropout(0.1))

# Шаг 2b – улучшение точности: добавление свёрточных слоёв
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))

# Шаг 3 : Преобразование в вектор
classifier.add(Flatten())

# Шаг 4 : Полное соединение (скрытый слой)
classifier.add(Dense(units=128, activation=’relu’))
# улучшение точности: добавление слоя
classifier.add(Dense(units=128, activation=’relu’))

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

# Компиляция CNN
classifier.compile(optimizer=”adam”, loss=”binary_crossentropy”, metrics=[‘accuracy’])

# Часть 2 : Подгонка CNN к изображениям
# 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)

# увеличение размера изображения для улучшения результатов
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)

# оценка модели
_, acc = classifier.evaluate_generator(test_set, steps=len(test_set), verbose=0)
print(‘> %.3f’ % (acc * 100.0))

summarize_diagnostics(history)

Мне бы хотелось построить матрицу путаницы и узнать, сколько изображений из обучающего набора. Это позволило бы мне получить результаты ложноположительных и ложноотрицательных.

Для этого я написал этот фрагмент кода:

#Матрица путаницы и отчет о классификации
Y_pred = classifier.predict_generator(training_set, 624 // batch_size+1)
y_pred = np.argmax(Y_pred, axis=1)
print(‘Матрица путаницы’)
matrix = cm(training_set.classes, y_pred)
print(matrix)
print(‘Отчет о классификации’)

print(cr(training_set.classes, y_pred))

При выполнении этих строк:

Я не получаю переменную matrix и получаю сообщение об ошибке:

ValueError: Найдены входные переменные с несогласованными числами образцов: [5216, 1280]

Я не уверен, что правильно задал матрицу путаницы.
Спасибо.

Это связано с разными формами, которые вы передаете в функцию cm. Вы передаете training_set.classes (которая будет иметь длину n_classes) и y_pred (которая будет иметь длину n_samples). Вместо того чтобы передавать training_set.classes, вы должны передать реальные метки для каждого образца, чтобы этот вектор также имел длину n_samples.

Ответ или решение

Чтобы построить матрицу путаницы для вашего проекта по классификации изображений с использованием свёрточной нейронной сети в Keras, вам необходимо правильно сравнить предсказанные метки и истинные метки классов. Ошибка, с которой вы столкнулись, связана с тем, что вы передаёте в функцию confusion_matrix массивы, которые не совпадают по длине. Давайте разберёмся, как правильно собрать матрицу путаницы.

Правильное построение матрицы путаницы

  1. Прогнозирование тестового набора: Вместо использования training_set, вам необходимо использовать test_set для получения предсказаний, поскольку вы хотите проанализировать работу модели на тестовых данных. Кроме того, важно убедиться, что количество изображений и их классы согласованы.

  2. Получение предсказаний: Вам нужно вызвать predict на тестовом наборе данных, а не на тренировочном.

  3. Приведение предсказаний к нужному формату: Так как вы используете бинарную классификацию, так как выходной слой у вас с активацией 'sigmoid', предсказанные значения будут находиться в диапазоне от 0 до 1. Вам следует применить порог классификации (обычно 0.5) для преобразования этих значений в метки классов (0 или 1).

Пример кода

Вот пример кода, где мы корректно получаем матрицу путаницы и отчет о классификации:

# Импорт необходимых библиотек
from keras.preprocessing.image import ImageDataGenerator
import numpy as np
from sklearn.metrics import classification_report, confusion_matrix

# Прогнозирование по тестовому набору
test_set.reset()  # Обновить состояние генератора, чтобы избежать смещения
Y_pred = classifier.predict(test_set, steps=len(test_set), verbose=1)
y_pred = (Y_pred > 0.5).astype(int)  # Применяем порог 0.5 для преобразования вероятностей в классы

# Получаем истинные метки классов
y_true = test_set.classes

# Построение матрицы путаницы и отчета о классификации
print('Confusion Matrix')
matrix = confusion_matrix(y_true, y_pred)
print(matrix)
print('Classification Report')
print(classification_report(y_true, y_pred, target_names=test_set.class_indices.keys()))

Объяснение кода

  1. Обновление генератора: test_set.reset() используется для сброса состояния генератора, чтобы обеспечить корректное получение предсказаний. Это особенно важно, когда генератор используется несколько раз.

  2. Предсказания: Мы вызываем метод predict, указывая количество шагов, равное количеству пакетов в тестовом наборе.

  3. Преобразование вероятностей: Предсказанные значения преобразуются в классы с помощью порога 0.5, где значения больше 0.5 будут интерпретированы как класс 1 (пневмония), а все остальные — как класс 0 (нормальный).

  4. Матрица путаницы и отчет: Обе метрики выводятся на экран. classification_report дает подробную информацию по метрикам, таким как точность, полнота и f1-мера для каждого класса.

Заключение

После того как вы скорректируете свой код согласно приведённым рекомендациям, вы сможете корректно сгенерировать матрицу путаницы и анализировать производительность вашей модели по классификации изображений. Убедитесь также, что в процессе обучения и валидации вы используете подходящие метрики, и протестируйте модель на репрезентативном наборе данных, чтобы избежать перекоса результатов.

Оцените материал
Добавить комментарий

Капча загружается...