I wanted to create an image compressor using Machine Learning and started work on an "AutoEncoder". This is a type of Neural Network which takes in the image and creates a compressed vector form.

It has two parts: encoder and decoder. encoder converts the images to vector form. decoder tries to re-create the image only from the vector created by the encoder.

This is how it looks like:


I have made the encoder a stack of Convolutional layers along with some MaxPooling2D ones. However, there is just a tiny problem.

The model performs well on any Image but it can be significantly improved.

For starters, the encoding dimension is too high! Right now with my calculations, I am getting a compression of 5 Mb -> 5Kb which is very lossy as the compression factor becomes x1000.

    import os
    import tensorflow as tf
    from keras.layers import Input, Dense, Conv2D, MaxPooling2D, UpSampling2D
    from keras.models import Model
    from keras import backend as K
    import numpy as np
    from keras.callbacks import ModelCheckpoint
    import matplotlib.pyplot as plt

    images_dir = "/content/drive/My Drive/Images/" # /{}.jpg".format(i)
    EPOCHS = 50

image_generator = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255)
train_data_gen = image_generator.flow_from_directory(directory=str(images_dir),
                                                     target_size=(600, 400),

input_img = Input(shape=(600, 400, 3))  # adapt this if using `channels_first` image data format

x = Conv2D(48, (3, 3), activation='relu', padding='same')(input_img)
x = MaxPooling2D((2, 2), padding='same')(x)                                    #ALl filters are upped by 16 and kernel size of encoder is 
x = Conv2D(80, (4, 4), activation='relu', padding='same')(x)                   # also upped by 1 and downed in decoder 
x = MaxPooling2D((2, 2), padding='same')(x)
x = Conv2D(144, (4, 4), activation='relu', padding='same')(x)
encoded = MaxPooling2D((1, 1), padding='same')(x)

# *************************

x = Conv2D(48, (4, 4), activation='relu', padding='same')(encoded)
x = UpSampling2D((2, 2))(x)
x = Conv2D(64, (4, 4), activation='relu', padding='same')(x)
x = UpSampling2D((2, 2))(x)
x = Conv2D(64, (1, 1), activation='relu')(x)             # DEfault = (2,2)
x = UpSampling2D((1, 1))(x)                               # Default = (2,2) 
decoded = Conv2D(3, (3, 3), activation='sigmoid', padding='same')(x)

    checkpoint_dir= "/content/drive/My Drive/Checkp_autoenc/"
    checkpoint_prefix = os.path.join(checkpoint_dir, "ckpt_{epoch}")

    checkpoint = ModelCheckpoint(filepath=checkpoint_prefix,

    autoencoder = Model(input_img, decoded)

    autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')



    decoded_imgs = autoencoder.predict(train_data_gen)

I had decided the filter and kernel values on a whim. But they can be adjusted to encompass more information so that the compression factor is reduced. As an example, here is what a sample image looks like:

As you can see clearly, this is very lossy and pixelated because the compression factor is really high. Also, the convolutional layers can also be flattened and the non-linearization function ReLu may be applied.

But I want some feedback from the experts to determine what areas are actually to be improved and what should be simply left alone. So I appreciate some constructive feedback and advice!

Very Lossy!

After a lot of studying and research, I managed to change the model sufficiently enough to produce a picture of significantly better quality images. But can it still be improved? Keep in mind the compression is x1000 meaning Image has been compressed over a 1000.


  • \$\begingroup\$ It appears that your indentation is incorrect at your imports at the top. Please fix this. \$\endgroup\$ – Reinderien Apr 27 at 16:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.