Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I split an convolutional autoencoder?

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))
like image 632
MegaNightdude Avatar asked Feb 03 '18 23:02

MegaNightdude


People also ask

How does a convolutional autoencoder work?

Instead of stacking the data, the Convolution Autoencoders keep the spatial information of the input image data as they are, and extract information gently in what is called the Convolution layer.

What is convolutional variational autoencoder?

Variational Autoencoder (VAE) Autoencoder is a neural network that is designed for unsupervised learning. It consists of 2 parts: encoder and decoder. The encoder aims to encode input features into encoding vectors, whereas the decoder obtains the output features back from the encoding vector.

How do I train my autoencoder model?

Unsupervised: To train an autoencoder we don't need to do anything fancy, just throw the raw input data at it. Autoencoders are considered an unsupervised learning technique since they don't need explicit labels to train on.

What is Lstm autoencoder?

LSTM autoencoder is an encoder that makes use of LSTM encoder-decoder architecture to compress data using an encoder and decode it to retain original structure using a decoder.


1 Answers

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')
like image 58
MegaNightdude Avatar answered Oct 06 '22 09:10

MegaNightdude