Как кормить модель Keras несколькими входами через fit_generator - PullRequest
0 голосов
/ 02 марта 2019

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

У меня естьиспользовал функцию ниже, чтобы настроить два генератора для модели.Это в значительной степени основывалось на ответе Симонста в В кератах, как согласовать несколько входных данных с различным типом , что было действительно полезно.

def create_generators(x_train_feat, x_val_feat, train_batch_size, val_batch_size):

    '''
    Training function
    '''

    train_datagen = ImageDataGenerator(
        featurewise_center=False,
        samplewise_center=False,
        featurewise_std_normalization=False,
        samplewise_std_normalization=False,
        zca_whitening=False,
        zca_epsilon=0,
        rotation_range=0.05,
        width_shift_range=0.05,
        height_shift_range=0.05,
        channel_shift_range=0,
        fill_mode='nearest',
        cval=0,
        vertical_flip=False,
        rescale=1./255,
        shear_range=0.,
        zoom_range=0.,
        horizontal_flip=False)


    val_datagen = ImageDataGenerator(
        rescale=1./255,
        featurewise_std_normalization=False,
        featurewise_center=False)


    train_generator=train_datagen.flow_from_dataframe(
        dataframe=subset_df_train,
        directory='./',
        x_col="image_path",
        y_col="Category_Name",
        batch_size=train_batch_size,
        seed=42,
        shuffle=True,
        class_mode="categorical",
        target_size=target_size)

    validation_generator = val_datagen.flow_from_dataframe(
        dataframe=subset_df_valid,
        directory="./",
        x_col="image_path",
        y_col="Category_Name",
        batch_size=val_batch_size,
        seed=42,
        shuffle=True,
        class_mode="categorical",
        target_size=target_size)

    def train_feat_gen(x_train_feat, train_batch_size):
        while True:
            for batch in range(len(x_train_feat) // train_batch_size + 1):
                if batch > max(range(len(x_train_feat) // train_batch_size)):
                    yield x_train_feat[batch*train_batch_size:]
                else:
                    yield x_train_feat[batch*train_batch_size:(1+batch)*train_batch_size]

    def val_feat_gen(x_val_feat, val_batch_size):
        while True:
            for batch in range(len(x_val_feat) // val_batch_size + 1):
                if batch > max(range(len(x_val_feat) // val_batch_size)):
                    yield x_val_feat[batch*val_batch_size:]
                else:
                    yield x_val_feat[batch*val_batch_size:(1+batch)*val_batch_size]

    def merge_generator(gen1, gen2):
        while True:
            X1 = gen1.__next__()
            X2 = gen2.__next__()
            yield [X1[0], X2], X1[1]



    final_train_gen = merge_generator(train_generator, train_feat_gen(x_train_feat, train_batch_size))
    final_val_gen = merge_generator(validation_generator, val_feat_gen(x_val_feat, val_batch_size))


    return (final_train_gen,final_val_gen)

final_train_gen,final_val_gen = create_generators(aux_train, aux_valid, 16, 16)

К сожалению, когда я затем запускаю модель скод ниже,

hist = model.fit_generator(
    final_train_gen,
    steps_per_epoch=train_len // 16,
    epochs=3,
    validation_data=final_val_gen,
    validation_steps=valid_len // 16)

Я обнаружил следующую ошибку: ValueError: Все входные массивы (x) должны иметь одинаковое количество выборок.Получил формы массива: [(16, 128, 128, 3), (0, 2160)].

Однако это происходит только во 2-й эпохе.Первый тренируется хорошо.Исходя из (0,2160), похоже, что 2-я эпоха не загружает партии (мой размер партии - 16) должным образом.К сожалению, поскольку у меня нет четкого представления о том, как работает вышеуказанная функция create_generators для объединения этих двух функций, я не очень уверен, в чем проблема, и был бы очень признателен за помощь / руководство по этому вопросу.

Извиняюсь за то, что код экспериментальный и, следовательно, немного сумбурный, а некоторый базовый контекст отсутствует - надеюсь, я включил достаточно информации, чтобы понять проблему.

Заранее спасибо.

1 Ответ

0 голосов
/ 14 мая 2019

Вы можете создать один генератор для сопряжения каждого изображения с соответствующим текстом.Просто передайте фрейм данных или файл с изображениями и текстами в функцию fit_generator и обработайте их так, чтобы они соответствовали вашим критериям (например, идентификатору), и получите массивы, которые имеют определенный размер, соответствующий желаемому пакету.размер.Затем вы можете получить кортеж, как в вашем коде, но теперь вы можете гарантировать, что размеры пакетов совпадают.Если вы действительно хотите использовать два генератора, вы можете посмотреть здесь: https://github.com/keras-team/keras/issues/8130

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...