Я пытаюсь воссоздать эту статью с кератами.
Основная идея 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 мс-потери. Вот некоторые восстановленные образцы: Это не лучший автокодер, но проблемы кроются где-то еще.
Далее я настроил предварительно обученный 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 тренировочных шагов восстановленные изображения выглядят так:
И после 1 эпохи изображения выглядят так:
Я полагаю, что в соединении обеих сетей есть что-то фундаментальное неправильное.
Я также обучил сеть на 100 эпох Оптимизатор SGD
optimizer = tf.keras.optimizers.SGD(learning_rate=0.0002, momentum=0.9, nesterov=False)
, где train_accuracy улучшился до 99%, но val_accuracy застрял на 47%, и восстановленные изображения выглядели так: