卷积自动编码器

时间:2020-05-05 13:30:06

标签: machine-learning keras deep-learning autoencoder

我正在编写用于在CIFAR10数据集上运行自动编码器的代码,并查看重建的图像。

要求是创建

编码器(具有第一层)

  • 输入形状:(32,32,3)
  • 具有64个(3,3)过滤器的Conv2D层
  • BatchNormalization层
  • 激活ReLu
  • 带有(2,2)过滤器的2D MaxpoolingLayer

编码器(第二层)

  • 具有16个滤镜(3,3)的Conv2D层
  • BatchNormalization层
  • 激活ReLu
  • 带有(2,2)过滤器的2D MaxpoolingLayer
  • 最终编码为(2,2)且包含所有先前图层的MaxPool

解码器(具有第一层)

  • 输入形状:编码器输出
  • 具有16个(3,3)滤镜的Conv2D层
  • BatchNormalization层
  • 激活ReLu
  • 具有(2,2)过滤器的UpSampling2D

解码器(第二层)

  • 具有32个(3,3)过滤器的Conv2D层
  • BatchNormalization层
  • 激活ReLu
  • 具有(2,2)过滤器的UpSampling2D
  • 最终解码为先前所有图层的Sigmoid

我了解

  1. 创建卷积自动编码器(或任何AE)时,需要将上一层的输出传递到下一层。
  2. 所以,当我用ReLu创建第一个Conv2D层然后执行BatchNormalization ..时,我在其中传递了Conv2D层..对吗?
  3. 但是当我执行MaxPooling2D ..我应该传递什么。。BatchNormalization输出或Conv2D层输出?

此外,我应该按照什么顺序执行这些操作?

  • Conv2D-> BatchNormalization-> MaxPooling2D
  • OR
  • Conv2D-> MaxPooling2D-> BatchNormalization

我在下面附加我的代码...我尝试了两种不同的方式,因此获得了不同的输出(就模型摘要和模型训练图而言)

有人可以通过解释哪种方法正确(方法1或方法2)来帮助我吗?另外,我如何理解哪个图显示了更好的模型性能?

方法-1

CREATE VIEW MostPop AS
SELECT KladNr, COUNT(KladNr) FROM OrderContent WHERE KladNr = 1;

作为模型摘要的输出,我得到了

总参数:18,851

可训练参数:18,851

不可训练参数:0

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)
                    )

Model Loss Graph - 1


方法-2

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()

作为模型摘要的输出,我得到了

总参数:19,363

可训练参数:19,107

不可训练的参数:256

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)
                        )

Model Loss Graph - 2

2 个答案:

答案 0 :(得分:1)

在方法1中,已编译模型中不存在BatchNormalization图层,因为这些图层的输出未在任何地方使用。您可以通过运行model1.summary()

进行检查

方法2完全正确。

操作顺序: Conv2D-> BatchNormalization-> MaxPooling2D通常是常见的方法。 尽管这两个顺序都可以使用,因为BatchNorm只是均值和方差归一化。

编辑:

对于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作为下一层的输入。

答案 1 :(得分:0)

要有效地使用 BatchNormalization 层,您应该始终在激活之前使用它。

代替:

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)

像这样使用它:

conv1_1 = Conv2D(64, (3, 3), padding='same')(input_image)
bnorm1_1 = BatchNormalization()(conv1_1)
act_1 = Activation('relu')(bnorm1_1)
mpool1_1 = MaxPooling2D((2, 2), padding='same')(act_1)

有关更多详细信息,请查看此处: Where do I call the BatchNormalization function in Keras?