如何拆分卷积自动编码器?
Posted
技术标签:
【中文标题】如何拆分卷积自动编码器?【英文标题】:How do I split an convolutional autoencoder? 【发布时间】:2018-07-14 04:09:41 【问题描述】:我已经编译了一个自动编码器(完整代码如下),在训练它之后,我想将它分成两个独立的模型:编码器(层 e1...编码)和解码器(所有其他层)在其中馈送手动修改已由解码器编码的图像。我已经成功地将编码器创建为一个单独的模型:
encoder = Model(input_img, autoencoder.layers[6].output)
但是当我尝试制作解码器时,同样的方法失败了:
encoded_input = Input(shape=(4,4,8))
decoder = Model(input_img, decoded)
这是我的完整代码:
from keras.layers import Input, Dense, Conv2D, MaxPooling2D, UpSampling2D
from keras.models import Model
from keras import backend as K
from keras.models import load_model
input_img = Input(shape=(28, 28, 1)) # adapt this if using channels_first` image data format
e1 = Conv2D(16, (3, 3), activation='relu', padding='same')(input_img)
e2 = MaxPooling2D((2, 2), padding='same')(e1)
e3 = Conv2D(8, (3, 3), activation='relu', padding='same')(e2)
e4 = MaxPooling2D((2, 2), padding='same')(e3)
e5 = Conv2D(8, (3, 3), activation='relu', padding='same')(e4)
encoded = MaxPooling2D((2, 2), padding='same')(e5)
# at this point the representation is (4, 4, 8) i.e. 128-dimensional
d1 = Conv2D(8, (3, 3), activation='relu', padding='same')(encoded)
d2 = UpSampling2D((2, 2))(d1)
d3 = Conv2D(8, (3, 3), activation='relu', padding='same')(d2)
d4 = UpSampling2D((2, 2))(d3)
d5 = Conv2D(16, (3, 3), activation='relu')(d4)
d6 = UpSampling2D((2, 2))(d5)
decoded = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(d6)
autoencoder = Model(input_img, decoded)
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')
请帮忙。
编辑 顺便说一句,我可以使用由密集层组成的自动编码器来做到这一点:
from keras.layers import Input, Dense
from keras.models import Model
# this is the size of our encoded representations
encoding_dim = 32 # 32 floats -> compression of factor 24.5, assuming the input is 784 floats
# this is our input placeholder
input_img = Input(shape=(784,))
# "encoded" is the encoded representation of the input
encoded = Dense(encoding_dim, activation='relu')(input_img)
# "decoded" is the lossy reconstruction of the input
decoded = Dense(784, activation='sigmoid')(encoded)
# this model maps an input to its reconstruction
autoencoder = Model(input_img, decoded)
# this model maps an input to its encoded representation
encoder = Model(input_img, encoded)
# create a placeholder for an encoded (32-dimensional) input
encoded_input = Input(shape=(encoding_dim,))
# retrieve the last layer of the autoencoder model
decoder_layer = autoencoder.layers[-1]
# create the decoder model
decoder = Model(encoded_input, decoder_layer(encoded_input))
【问题讨论】:
尝试遵循answer中显示的想法。 【参考方案1】:好的,我在几个小时后发现了这一点。对我有用的是: 1.为编码器创建一个单独的模型 2.为解码器创建一个单独的模型 3.为自动编码器创建一个通用模型:
autoencoder = Model(input, Decoder()(Encoder(input))
完整的工作代码如下:
def Encoder():
input_img = Input(shape=(28, 28, 1)) # adapt this if using `channels_first` image data format
e1 = Conv2D(16, (3, 3), activation='relu', padding='same')(input_img)
e2 = MaxPooling2D((2, 2), padding='same')(e1)
e3 = Conv2D(8, (3, 3), activation='relu', padding='same')(e2)
e4 = MaxPooling2D((2, 2), padding='same')(e3)
e5 = Conv2D(8, (3, 3), activation='relu', padding='same')(e4)
e6 = MaxPooling2D((2, 2), padding='same')(e5)
return Model(input_img, e6)
def Decoder():
input_img = Input(shape=(4, 4, 8)) # adapt this if using `channels_first` image data format
d1 = Conv2D(8, (3, 3), activation='relu', padding='same')(input_img)
d2 = UpSampling2D((2, 2))(d1)
d3 = Conv2D(8, (3, 3), activation='relu', padding='same')(d2)
d4 = UpSampling2D((2, 2))(d3)
d5 = Conv2D(16, (3, 3), activation='relu')(d4)
d6 = UpSampling2D((2, 2))(d5)
d7 = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(d6)
return Model(input_img, d7)
# define input to the model:
x = Input(shape=(28, 28, 1))
# make the model:
autoencoder = Model(x, Decoder()(Encoder()(x)))
# compile the model:
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')
【讨论】:
这可行,但真正的问题是,在自动编码器经过训练之后,如何提取编码器/解码器组件 @pcko1 这已经有一段时间了,但我认为您至少可以使用 get_weights() 获取层权重,或者您可以将autoencoder = Model(x, d(e(x)))
设为d = Decoder()
和e = Encoder()
。训练自编码器后,您可以分别使用d
和e
。
是的,正确!我只是想知道是否可以训练任意复杂的网络,然后将其拆分为两个子模型,而无需在训练之前将网络明确定义为两个子模型的模型。不过不用担心,你的方案也适用于我:)以上是关于如何拆分卷积自动编码器?的主要内容,如果未能解决你的问题,请参考以下文章