Как получить путаницу при использовании 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

Другие вопросы по тегам