pythonmachine-learningdeep-learningautoencoderencoder

Get the output of just bottleneck layer from autoencoder


I'm new to Autoencoder. I have built a simple convolution autoencoder as shown below:

# ENCODER
input_img = Input(shape=(64, 64, 1))

encode1 = Conv2D(32, (3, 3), activation=tf.nn.leaky_relu, padding='same')(input_img) 
encode2 = MaxPooling2D((2, 2), padding='same')(encode1)
l = Flatten()(encode2)
l = Dense(100, activation='linear')(l)

# DECODER
d = Dense(1024, activation='linear')(l) 
d = Reshape((32,32,1))(d)
decode3 = Conv2D(64, (3, 3), activation=tf.nn.leaky_relu, padding='same')(d) 
decode4 = UpSampling2D((2, 2))(decode3)

model = models.Model(input_img, decode4)

model.compile(optimizer='adam', loss='mse')

# Train it by providing training images
model.fit(x, y, epochs=20, batch_size=16)

Now after training this model, I want to get output from bottleneck layer i.e dense layer. That means if I throw array of shape (1000, 64, 64) to model, I want compressed array of shape (1000, 100).

I have tried one method as shown below, but it's giving me some error.

model = Model(inputs=[x], outputs=[l])

err:

ValueError: Input tensors to a Functional must come from `tf.keras.Input`.

I have also tried some other method but that's also not working. Can someone tell me how can I get compressed array back after training the model.


Solution

  • You need to create the separate model for the encoder. After you train the whole system encoder-decoder, you can use only encoder for prediction. Code example:

    # ENCODER
    input_img = layers.Input(shape=(64, 64, 1))
    encode1 = layers.Conv2D(32, (3, 3), activation=tf.nn.leaky_relu, padding='same')(input_img) 
    encode2 = layers.MaxPooling2D((2, 2), padding='same')(encode1)
    l = layers.Flatten()(encode2)
    encoder_output = layers.Dense(100, activation='linear')(l)
    
    # DECODER
    d = layers.Dense(1024, activation='linear')(encoder_output) 
    d = layers.Reshape((32,32,1))(d)
    decode3 = layers.Conv2D(64, (3, 3), activation=tf.nn.leaky_relu, padding='same')(d) 
    decode4 = layers.UpSampling2D((2, 2))(decode3)
    
    model_encoder = Model(input_img, encoder_output)
    model = Model(input_img, decode4)
    
    model.fit(X, y, epochs=20, batch_size=16)
    

    model_encoder.predict(X) should return a vector for each image.