Как получить путаницу при использовании model.fit_generator
Я использую model.fit_generator для обучения и получения результатов для моей двоичной (двухклассной) модели, потому что я даю входные изображения прямо из своей папки. Как получить путаницу в этом случае (TP, TN, FP, FN), потому что обычно я использую confusion_matrix
командование sklearn.metrics
чтобы получить это, что требует predicted
, а также actual
этикетки. Но здесь у меня нет обоих. Может быть, я могу рассчитать прогнозные метки из predict=model.predict_generator(validation_generator)
команда. Но я не знаю, как моя модель берет входные метки с моих изображений. Общая структура моей входной папки:
train/
class1/
img1.jpg
img2.jpg
........
class2/
IMG1.jpg
IMG2.jpg
test/
class1/
img1.jpg
img2.jpg
........
class2/
IMG1.jpg
IMG2.jpg
........
и некоторые блоки моего кода:
train_generator = train_datagen.flow_from_directory('train',
target_size=(50, 50), batch_size=batch_size,
class_mode='binary',color_mode='grayscale')
validation_generator = test_datagen.flow_from_directory('test',
target_size=(50, 50),batch_size=batch_size,
class_mode='binary',color_mode='grayscale')
model.fit_generator(
train_generator,steps_per_epoch=250 ,epochs=40,
validation_data=validation_generator,
validation_steps=21 )
Таким образом, приведенный выше код автоматически принимает два входных данных класса, но я не знаю, для какого он рассматривает класс 0, а для какого класса 1.
2 ответа
Я справился с этим следующим образом, используя keras.utils.Sequence
,
from sklearn.metrics import confusion_matrix
from keras.utils import Sequence
class MySequence(Sequence):
def __init__(self, *args, **kwargs):
# initialize
# see manual on implementing methods
def __len__(self):
return self.length
def __getitem__(self, index):
# return index-th complete batch
# create data generator
data_gen = MySequence(evaluation_set, batch_size=10)
n_batches = len(data_gen)
confusion_matrix(
np.concatenate([np.argmax(data_gen[i][1], axis=1) for i in range(n_batches)]),
np.argmax(m.predict_generator(data_gen, steps=n_batches), axis=1)
)
Реализованный класс возвращает пакеты данных в кортежах, что позволяет не хранить их все в оперативной памяти. Обратите внимание, что это должно быть реализовано в __getitem__
и этот метод должен возвращать один и тот же пакет для одного и того же аргумента.
К сожалению, этот код повторяет данные дважды: в первый раз он создает массив истинных ответов из возвращенных пакетов, во второй раз он вызывает predict
метод модели.
probabilities = model.predict_generator(generator=test_generator)
даст нам набор вероятностей.
y_true = test_generator.classes
даст нам настоящие ярлыки.
Поскольку это проблема двоичной классификации, вам необходимо найти предсказанные метки. Для этого вы можете использовать
y_pred = probabilities > 0.5
Тогда у нас есть истинные метки и предсказанные метки в тестовом наборе данных. Итак, матрица путаницы имеет вид
font = {
'family': 'Times New Roman',
'size': 12
}
matplotlib.rc('font', **font)
mat = confusion_matrix(y_true, y_pred)
plot_confusion_matrix(conf_mat=mat, figsize=(8, 8), show_normed=False)
Вы можете просмотреть отображение имен классов на индексы классов, вызвав атрибут class_indices
на ваше train_generator
или же validation_generator
объекты, как в
train_generator.class_indices