Сверточные автоэнкодеры - PullRequest
0 голосов
/ 05 мая 2020

Я пишу код для запуска автокодера в наборе данных CIFAR10 и вижу реконструированные изображения.

Требуется создать

Кодировщик с первым слоем

  • Форма ввода: (32,32,3)
  • Слой Conv2D с 64 фильтрами (3,3)
  • слой BatchNormalization
  • Активация ReLu
  • 2D MaxpoolingLayer с фильтром (2,2)

Encoder со вторым слоем

  • Conv2D слой с 16 фильтрами (3,3)
  • Слой BatchNormalization
  • Активация ReLu
  • 2D MaxpoolingLayer с фильтром (2,2)
  • Окончательная кодировка как MaxPool с (2,2) со всеми предыдущими слоями

Декодер с первым слоем

  • Форма ввода: выход кодировщика
  • Слой Conv2D с 16 фильтрами (3,3)
  • Слой BatchNormalization
  • Активация ReLu
  • UpSampling2D с фильтром (2,2)

Декодер со вторым слоем

  • Слой Conv2D с 32 фильтрами (3,3)
  • Слой BatchNormalization
  • Активация ReLu
  • UpSampling2D с фильтром (2,2)
  • Final Декодируется как сигмоид со всеми предыдущими слоями

Я понимаю, что

  1. Когда мы создаем сверточный автоэнкодер (или любой AE), нам нужно передать вывод предыдущего слоя на следующий уровень.
  2. Итак, когда я создаю первый слой Conv2D с помощью ReLu, а затем выполняю BatchNormalization .. в котором я передаю слой Conv2D .. верно?
  3. Но когда я делаю MaxPooling2D .. что я должен передать .. Вывод BatchNormalization или слой Conv2D вывод?

Кроме того, существует ли порядок, в котором я должен выполнять эти операции?

  • Conv2D -> BatchNormalization -> MaxPooling2D
  • ИЛИ
  • Conv2D -> MaxPooling2D -> BatchNormalization

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

Может ли кто-нибудь помочь мне, объяснив какой метод правильный (метод 1 или метод 2)? Кроме того, как мне понять, какой график показывает лучшую производительность модели?

Метод - 1

input_image = Input(shape=(32, 32, 3))

### Encoder
conv1_1 = Conv2D(64, (3, 3), activation='relu', padding='same')(input_image)
bnorm1_1 = BatchNormalization()(conv1_1)
mpool1_1 = MaxPooling2D((2, 2), padding='same')(conv1_1)

conv1_2 = Conv2D(16, (3, 3), activation='relu', padding='same')(mpool1_1)
borm1_2 = BatchNormalization()(conv1_2)

encoder = MaxPooling2D((2, 2), padding='same')(conv1_2)

### Decoder
conv2_1 = Conv2D(16, (3, 3), activation='relu', padding='same')(encoder)
bnorm2_1 = BatchNormalization()(conv2_1)
up1_1 = UpSampling2D((2, 2))(conv2_1)

conv2_2 = Conv2D(32, (3, 3), activation='relu', padding='same')(up1_1)
bnorm2_2 = BatchNormalization()(conv2_2)
up2_1 = UpSampling2D((2, 2))(conv2_2)

decoder = Conv2D(3, (3, 3), activation='sigmoid', padding='same')(up2_1)

model = Model(input_image, decoder)
model.compile(optimizer='adam', loss='binary_crossentropy')
model.summary()

history = model.fit(trainX, trainX, 
                    epochs=50, 
                    batch_size=1000, 
                    shuffle=True,
                    verbose=2,
                    validation_data=(testX, testX)
                    )

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

Всего параметров: 18,851

Обучаемые параметры: 18,851

Необучаемые параметры: 0

plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper right')
plt.show()

Model Loss Graph - 1


Method - 2

input_image = Input(shape=(32, 32, 3))

### Encoder
x = Conv2D(64, (3, 3), activation='relu', padding='same')(input_image)
x = BatchNormalization()(x)
x = MaxPooling2D((2, 2), padding='same')(x)

x = Conv2D(16, (3, 3), activation='relu', padding='same')(x)
x = BatchNormalization()(x)

encoder = MaxPooling2D((2, 2), padding='same')(x)

### Decoder

x = Conv2D(16, (3, 3), activation='relu', padding='same')(encoder)
x = BatchNormalization()(x)
x = UpSampling2D((2, 2))(x)

x = Conv2D(32, (3, 3), activation='relu', padding='same')(x)
x = BatchNormalization()(x)
x = UpSampling2D((2, 2))(x)

decoder = Conv2D(3, (3, 3), activation='sigmoid', padding='same')(x)

model = Model(input_image, decoder)
model.compile(optimizer='adam', loss='binary_crossentropy')
model.summary()

history = model.fit(trainX, trainX, 
                        epochs=50, 
                        batch_size=1000, 
                        shuffle=True,
                        verbose=2,
                        validation_data=(testX, testX)
                        )

As an output of the model summary, I get this

Total params: 19,363

Trainable params: 19,107

Non-trainable params: 256

plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper right')
plt.show()

График потерь модели - 2

1 Ответ

1 голос
/ 05 мая 2020

В методе 1 слои BatchNormalization не существуют в скомпилированной модели, так как выходные данные этих слоев нигде не используются. Вы можете проверить это, запустив model1.summary()

Метод 2 совершенно нормальный.

Порядок операций: Conv2D -> BatchNormalization -> MaxPooling2D обычно является обычным подходом. Хотя любой порядок будет работать с тех пор, поскольку BatchNorm - это просто нормализация среднего и дисперсии.

Edit:

Для Conv2D -> BatchNormalization -> MaxPooling2D:

conv1_1 = Conv2D(64, (3, 3), activation='relu', padding='same')(input_image) bnorm1_1 = BatchNormalization()(conv1_1) mpool1_1 = MaxPooling2D((2, 2), padding='same')(bnorm1_1), а затем используйте mpool1_1 в качестве входных данных для следующего слоя.

Для Conv2D -> MaxPooling2D -> BatchNormalization:

conv1_1 = Conv2D(64, (3, 3), activation='relu', padding='same')(input_image) mpool1_1 = MaxPooling2D((2, 2), padding='same')(conv1_1) bnorm1_1 = BatchNormalization()(mpool1_1) и затем используйте bnorm1_1 в качестве входных данных для следующего слой.

...