问题
I have compiled an autoencoder (full code is below), and after training it I would like to split it into two separate models: encoder (layers e1...encoded) and decoder (all other layers) in which to feed manually modified images that had been encoded by the decoder. I have succeeded in creating an encoder as a separate model with:
encoder = Model(input_img, autoencoder.layers[6].output)
But the same approach fails when I try to make a decoder:
encoded_input = Input(shape=(4,4,8))
decoder = Model(input_img, decoded)
This is my full code:
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')
Plese help.
EDIT By the way, I was able to do this with an autoencoder consisting of dense layers:
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))
回答1:
Ok, I figured this out after a few hours. What worked for me was to: 1. Create a separate model for the encoder 2. Create a separate model for teh decoder 3. Create a general model for the autoencoder:
autoencoder = Model(input, Decoder()(Encoder(input))
The full working code is below:
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')
来源:https://stackoverflow.com/questions/48603328/how-do-i-split-an-convolutional-autoencoder