Подключение автоэнкодера и CNN - PullRequest
0 голосов
/ 03 марта 2020

Я пытаюсь воссоздать эту статью с кератами.

Основная идея c заключается в следующем:

  • предварительная подготовка автоэнкодера и сети классификатора отдельно
  • замораживание весов сети кодировщика и классификатора
  • объединение обеих сетей, точная настройка декодера и просмотр способа декодирования сетью изображений для классификатора

Автоэнкодер и сеть классификаторов работают нормально сами по себе, но когда я подключаю их и позволяю декодеру тренироваться, кажется, что происходит что-то странное.

Итак, это мой автоэнкодер

    def create_autoencoder(self, filters=[20, 40, 80, 160, 320], kernel=(3,3), stride=(1,1), strideundo=2, pool=(2,2)):
        # define encoder architecture
        self.encoder = tf.keras.models.Sequential()
        self.encoder.add(tf.keras.layers.InputLayer(self.input_shape))
        for i in range(len(filters)):
            self.encoder.add(tf.keras.layers.Conv2D(filters=filters[i], kernel_size=kernel, strides=stride, activation='elu', padding='same'))
            self.encoder.add(tf.keras.layers.MaxPooling2D(pool_size=pool))
            #self.encoder.add(tf.keras.layers.AveragePooling2D(pool_size=pool))

        # define decoder architecture
        self.decoder = tf.keras.models.Sequential()
        for i in range(1,len(filters)):
            self.decoder.add(tf.keras.layers.Conv2DTranspose(filters=filters[len(filters)-i], kernel_size=kernel, strides=strideundo, activation='elu', padding='same'))
        self.decoder.add(    tf.keras.layers.Conv2DTranspose(filters=self.input_shape[2],kernel_size=kernel, strides=strideundo, activation='sigmoid',  padding='same'))

        # compile model
        input         = tf.keras.layers.Input(self.input_shape)
        code          = self.encoder(input)
        reconstructed = self.decoder(code)

        self.model = tf.keras.models.Model(inputs=input, outputs=reconstructed)

после 100 эпох на Набор данных cats_vs_dogs, я получу около 0,005 мс-потери. Вот некоторые восстановленные образцы: Reconstructed images Это не лучший автокодер, но проблемы кроются где-то еще.

Далее я настроил предварительно обученный MobileNetV2 на наборе данных cats_vs_dogs и получил около 98 % точности Как и в этом руководстве .

Сохранение и восстановление весов / моделей обеих моделей работает просто отлично. Допустим, я восстанавливаю / создаю их следующим образом.

autoencoder = create_autoencoder()
autoencoder.model.load_weights("/weights/cae_weight.hdf5")
mobileNet2 = load_model("/weights/checkpoint_mobileNet/mobileNetV2_finetuned.h5")

И только позволяю декодеру обучаться

autoencoder.encoder.trainable = False
mobileNet2.trainable = False
autoencoder.decoder.trainable = True

Подключение обеих моделей

combinedModels = tf.keras.Sequential([autoencoder.model, mobileNet2])

Я компилирую подключенный Модели

combinedModels.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=0.0002,momentum=0.9,nesterov=False),
              loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              metrics=['accuracy'])

И обучаем их

history = combinedModels.fit(train_batches, epochs=1, validation_data=validation_batches, validation_steps=20, shuffle=True)

После 5 тренировочных шагов восстановленные изображения выглядят так: reconstructed images after 5 training steps

И после 1 эпохи изображения выглядят так: reconstructed images after 1 epoch

Я полагаю, что в соединении обеих сетей есть что-то фундаментальное неправильное.

Я также обучил сеть на 100 эпох Оптимизатор SGD

optimizer = tf.keras.optimizers.SGD(learning_rate=0.0002, momentum=0.9, nesterov=False)

, где train_accuracy улучшился до 99%, но val_accuracy застрял на 47%, и восстановленные изображения выглядели так:

enter image description here

...