Keras: невозможно добавить плотный слой в VGG16.

Я пытаюсь настроить последний блок свертки vgg16 (предварительно обученный образ) с добавлением нескольких плотных слоев сверху. Мой код ниже. Я не могу понять, почему я получаю эту ошибку при выполнении Error when checking target: expected sequential_9 to have shape (None, 11) but got array with shape (4, 1). Количество классов в моем наборе данных — 11, а размер пакета — 4. Я как-то смешиваю эти два? Пожалуйста помоги.

def finetune( epochs):

    num_classes = 11
    batch_size = 4
    base_model = VGG16(weights='imagenet', include_top=False, input_shape = (224,224,3))
    print('Model loaded.')
    print(base_model.output_shape[1:])
    top_model = Sequential()  
    top_model.add(Flatten(input_shape=base_model.output_shape[1:])) 
    top_model.add(Dense(512, activation='relu',kernel_regularizer=regularizers.l2(0.01)))
    top_model.add(Dropout(0.25))
    top_model.add(Dense(256, activation='relu', kernel_regularizer=regularizers.l2(0.01)))  
    top_model.add(Dropout(0.25))  
    top_model.add(Dense(num_classes, activation='softmax')) 


    top_model.load_weights('vgg_ft_best.h5')

    # add the model on top of the convolutional base
    #model = Model(inputs= base_model.input, outputs= top_model(base_model.output))

    #base_model.add(top_model)
    #print(base_model.summary())

    new_model = Sequential()
    for l in base_model.layers:
        new_model.add(l)


    # CONCATENATE THE TWO MODELS
    new_model.add(top_model)
    print(new_model.summary())

    # set the first 10 layers (up to the last conv block)
    # to non-trainable (weights will not be updated)
    for layer in new_model.layers[:11]:
        layer.trainable = False

    # prepare data augmentation configuration
    train_datagen = ImageDataGenerator(
        rescale=1. / 255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)

    train_data_dir = "./images/train"
    validation_data_dir = "./images/validation"
    test_datagen = ImageDataGenerator(rescale=1. / 255)

    train_generator = train_datagen.flow_from_directory(
        train_data_dir,
        target_size=(224, 224),
        batch_size=batch_size,
        class_mode='binary')

    validation_generator = test_datagen.flow_from_directory(
        validation_data_dir,
        target_size=(224, 224),
        batch_size=batch_size,
        class_mode='binary')

    num_train_samples = len(train_generator.filenames) 
    num_validation_samples = len(validation_generator.filenames)
    print(num_validation_samples)
    new_model.compile(loss='categorical_crossentropy',
              optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
              metrics=['accuracy'])
    # fine-tune the model

    new_model.fit_generator(
        train_generator,
        steps_per_epoch=int(num_train_samples/batch_size),
        epochs=epochs,
        validation_data=validation_generator,
        validation_steps = int(num_validation_samples/batch_size))

person user1274878    schedule 09.02.2018    source источник


Ответы (1)


Проблема в ваших данных (цель = истинные результаты, истинные метки и т. д.).

Ваша цель имеет форму (batch,1), а ваша модель с 11 классами ожидает (batch,11)

Значит проблема в вашем генераторе. Он должен выводить тензоры с 11 классами.

Для этого см. документацию для flow_from_directory и выделенные части:

классы: необязательный список подкаталогов классов (например, ['dogs', 'cats']). По умолчанию: Нет. Если он не указан, список классов будет автоматически выведен из имен/структуры подкаталогов в каталоге, где каждый подкаталог будет рассматриваться как отдельный класс (и порядок классов, который будет отображаться в индексы меток будут буквенно-цифровыми). Словарь, содержащий отображение имен классов на индексы классов, можно получить через атрибут class_indices.

class_mode: категориальный, двоичный, разреженный, входной или None. По умолчанию: категорический. Определяет тип возвращаемых массивов меток: категориальные будут двухмерными метками с горячим кодированием, двоичные будут одномерными двоичными метками, разреженные будут одномерными целочисленными метками, входными будут изображения, идентичные входным изображениям ( в основном используется для работы с автоэнкодерами). Если None, метки не возвращаются (генератор будет выдавать только пакеты данных изображения, что полезно для использования model.predict_generator(), model.evaluate_generator() и т. д.). Обратите внимание, что в случае class_mode None данные все равно должны находиться в подкаталоге каталога, чтобы они работали правильно.

Решение

  • Вам нужно разместить изображения в 11 разных папках, каждая из которых относится к другому классу.
  • Вам нужно использовать class_mode='categorical', чтобы иметь формат (batch,11).

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

person Daniel Möller    schedule 09.02.2018