我想将自动编码器的学习和应用分为以下两个部分:https://blog.keras.io/building-autoencoders-in-keras.html,并使用fashion-mnist数据进行测试:
加载图像,进行可能需要数小时或数天的拟合,然后使用回调保存最佳的自动编码器模型。该过程可能在下一部分之前几周。
使用最佳模型(由文件名手动选择)并绘制原始图像,由自动编码器的编码器进行的编码表示以及使用自动编码器的解码器进行的预测。我在从训练有素的自动编码器中提取编码器和解码器层时遇到问题(请参阅第二步)。
对于第一步,我有一个非常简单的网络,如下所示:
input_img = Input(shape=(784,)) # encoded representation encoded = Dense(encoding_dim, activation='relu')(input_img) # lossy reconstruction decoded = Dense(784, activation='sigmoid')(encoded) # full AE model: map an input to its reconstruction autoencoder = Model(input_img, decoded) # encoder: map an input to its encoded representation encoder = Model(input_img, encoded) # placeholder for an encoded input encoded_input = Input(shape=(encoding_dim,)) # last layer of the autoencoder model decoder_layer = autoencoder.layers[-1] # decoder decoder = Model(encoded_input, decoder_layer(encoded_input))
网络是:
autoencoder.summary() _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_5 (InputLayer) (None, 784) 0 _________________________________________________________________ dense_5 (Dense) (None, 32) 25120 _________________________________________________________________ dense_6 (Dense) (None, 784) 25872 =================================================================
和
encoder.summary() _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_5 (InputLayer) (None, 784) 0 _________________________________________________________________ dense_5 (Dense) (None, 32) 25120 =================================================================
所以我训练模型并通过保存autoencoder.save('fashion-autoencoder.hdf5')
。在我的真实示例中,我使用回调将其保存,因此通过保存编码器和解码器的解决方法似乎不是真正的解决方案。后来我加载图像(未显示)并进行如下预测
# encode and decode some images from test set encoded_imgs = encoder.predict(x_test) decoded_imgs = decoder.predict(encoded_imgs) # test the shape print(encoded_imgs[0].shape)
并得到一个形状(32,0)
。
因此,让我们继续进行我遇到问题的两个步骤2。我使用加载模型
encoder= K.models.load_model('fashion-autoencoder.hdf5') # delete the last layers to get the encoder encoder.layers.pop() encoder.summary() # show model data
并且编码器看起来与第一步中的原始编码器相同,这让我认为提取效果很好:
Layer (type) Output Shape Param # ================================================================= input_5 (InputLayer) (None, 784) 0 _________________________________________________________________ dense_5 (Dense) (None, 32) 25120 ================================================================= Total params: 50,992 Trainable params: 50,992 Non-trainable params: 0
但我也得到警告
training.py:478: UserWarning: Discrepancy between trainable weights and collected trainable weights, did you set `model.trainable` without calling `model.compile` after ? 'Discrepancy between trainable weights and collected trainable'
我以某种方式理解但不知道它有多重要。然后我再次加载图像(未显示)并使用编码器
encoded_imgs = encoder.predict(x_test) # test the shape print(encoded_imgs[0].shape)
但是形状不合适(784,)
。
因此,由于尺寸不正确,我无法提取编码器。我什至没有成功提取解码器(形成保存自动编码器),因为我无法使用push()
和尝试类似的东西,decoder = decoder.layers[-1:-2]
但是它不起作用。
因此,我的一般问题是如何提取部分加载的模型。
由于您使用功能性API来创建自动编码器,因此重构编码器和解码器的最佳方法是再次使用功能性API和Model
类:
autoencoder= K.models.load_model('fashion-autoencoder.hdf5') encoder = Model(autoencoder.input, autoencoder.layers[-2].output) decoder_input = Input(shape=(encoding_dim,)) decoder = Model(decoder_input, autoencoder.layers[-1](decoder_input)) encoder.summary() decoder.summary()
型号汇总:
Layer (type) Output Shape Param # ================================================================= input_4 (InputLayer) (None, 784) 0 _________________________________________________________________ dense_3 (Dense) (None, 32) 25120 ================================================================= Total params: 25,120 Trainable params: 25,120 Non-trainable params: 0 _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_6 (InputLayer) (None, 32) 0 _________________________________________________________________ dense_4 (Dense) (None, 784) 25872 ================================================================= Total params: 25,872 Trainable params: 25,872 Non-trainable params: 0 _________________________________________________________________
涉及pop()
on layers
属性的解决方案不起作用,因为您需要更新模型的某些内部属性。虽然,对于顺序模型,pop()
已实现了内置方法。