Тот же ImageDataGenerator, но разные class_indices - Как переназначить классы в генераторе? - PullRequest
0 голосов
/ 26 ноября 2018

Фон

Я тренирую модель, которая принимает в качестве входных данных два изображения.Поскольку данные слишком велики, чтобы поместиться в оперативную память моих машин, я использую flow_from_dataframe для создания генераторов для обучения и проверки - два обучающих генератора, каждый из которых предоставляет одно из соответствующих изображений (вид спереди и вид сзади, как указано x_col параметр) и два генератора для проверки соответственно.

Примерно так:

datagen=ImageDataGenerator(rescale=1. / 255)

X1_train_generator =datagen.flow_from_dataframe(dataframe=train, directory=data_dir, x_col="front", y_col=target, has_ext=True, class_mode="categorical", target_size=(224,224), batch_size=batch_size,seed = 1)
X2_train_generator=datagen.flow_from_dataframe(dataframe=train, directory=data_dir, x_col="back", y_col=target, has_ext=True, class_mode="categorical", target_size=(224,224), batch_size=batch_size,seed = 1)

X1_validation_generator =datagen.flow_from_dataframe(dataframe=test, directory=data_dir, x_col="front", y_col=target, has_ext=True, class_mode="categorical", target_size=(224,224), batch_size=batch_size,seed = 1)
X2_validation_generator=datagen.flow_from_dataframe(dataframe=test, directory=data_dir, x_col="back", y_col=target, has_ext=True, class_mode="categorical", target_size=(224,224), batch_size=batch_size,seed = 1)

Чтобы объединить поезд и генератор проверки для обучения, я использую:

def format_gen_outputs(gen1,gen2):
    x1 = gen1[0]
    x2 = gen2[0]
    y1 = gen1[1]
    return [x1, x2], y1

train_combo_gen= map(format_gen_outputs, X1_train_generator , X2_train_generator )
validation_combo_gen= map(format_gen_outputs, X1_validation_generator , X2_validation_generator )

Теперь я использую fit_generator для обучения моей модели, передавая train_combo_gen для целей обучения и validation_combo_gen параметру validation_data для целей проверки

Задача

Однако я понимаю,что мои X1_train_generator и X2_train_generator показывают другое отображение .class_indices, чем два других моих генератора проверки X1_validation_generator и X2_validation_generator.

Примерно так (обратите внимание, как кошка и собака назначаются различным классам):

X1_train_generator.class_indices
>> {'cat': 0, 'dog': 1, 'car': 2, 'bike': 3}

X1_validation_generato.class_indices
>> {'dog': 0, 'cat': 1, 'car': 2, 'bike': 3}

Вопрос

Следовательно, я не доверяю своим val_loss и val_acc во время тренировок.Есть ли способ исправить это, то есть переназначить классы в генераторах?

1 Ответ

0 голосов
/ 27 ноября 2018

Если вы явно не задаете классы с помощью аргумента classes, flow_from_dataframe внутренне использует pandas Series unique для столбца y_col , чтобы найти классы :

if not classes:
    classes = []
    if class_mode not in ["other", "input", None]:
        classes = list(self.df[y_col].unique())

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

Один из обходных путей - явная установка аргумента classes для всех flow_from_dataframeзвонки, чтобы гарантировать отображение одинаковых индексов классов в генераторах поездов и валидации:

X1_train_generator =datagen.flow_from_dataframe(dataframe=train, 
                                                classes=['cat', 'dog', 'car', 'bike'], ...)

# do the same for `X2_train_generator`, `X1_validation_generator` and `X2_validation_generator`
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...