AutoEncoder Resulting In (61,61,3) instead of (64,64,3)

Viewed 102

I am trying to build a convolutional autoencoder. Here is my architecture.


def MainEncoder():
    inp = Input(shape=(64,64,3))
    x = Conv2D(256,2)(inp)
    x = MaxPool2D()(x)
    x = Conv2D(128,2)(x)
    x = Flatten()(x)
    encoded = Dense(100,activation="relu")(x)

    encoder= Model(inp,encoded)
    return encoder


def Decoder():
    enc = Input(shape=(100,))
    y = Dense(128)(enc)
    y = Dense(768)(y)
    y= Reshape((16,16,3))(y)
    y= Conv2DTranspose(128,(1,1),(2,2),padding='same')(y)
    y= Conv2DTranspose(128,(1,1),(2,2),padding='same')(y)
    decoded1 = Conv2D(3,1,padding="same")(y)
    decoder = Model(enc,decoded1)
    return decoder
encoder= MainEncoder()

decoderA = Decoder()
decoderB = Decoder()

print(encoder.summary())
print(decoderA.summary())
print(decoderB.summary())
input()
#decoder=  Model(encoded_input,decoded1)
#print(decoder.summary())
Inp = Input(shape=(64,64,3))
Inp2 = Input(shape=(64,64,3))
AutoEncoder1 = Model(Inp,decoderA(encoder(Inp)))
AutoEncoder2 = Model(Inp2,decoderB(encoder(Inp2)))
AutoEncoder1.summary()
AutoEncoder2.summary()
print(ot[0].shape)
input()
AutoEncoder1.compile(optimizer='adam',loss='mse')
AutoEncoder2.compile(optimizer='adam',loss='mse')
AutoEncoder1.fit(ot,ot,16,100)
AutoEncoder2.fit(kt,kt,16,100)
encoder.save(path+'encoder')
decoderA.save(path+'obama')
decoderB.save(path+'kimmel')



The outputs of all models and shapes of all images are 64,64,3 according to the summary. However whenever I try to add the accuracy metric or just test out the auto encoder it always results in and image of size 61,61,3. I don't really know how to fix this. Any help would be appreciated.

Here is the test code


from numpy.core.shape_base import block
import tensorflow as tf

from tensorflow.keras.layers import *
from tensorflow.keras.models import *
import pickle
import numpy as np
import matplotlib.pyplot as plt
path = 'youtube_stuff2/'
ot = pickle.load(open(path+'oi.pickle','rb'))
kt = pickle.load(open(path+'ki.pickle','rb'))
ot = ot/255.0
kt = kt/255.0
encoder = load_model(path+'encoder')
obama = load_model(path+"obama")
kimmel = load_model(path+"kimmel")
print(ot[0].shape)
ott = np.array([ot[0]])
print(ott.shape)
thing = encoder.predict(ott)
image = obama.predict(thing)
print(image.shape)
#plt.imshow(ott[0])
plt.imshow(image[0])
plt.show()



The variable image has shape (61,61,3)

1 Answers

When using Convolution, you need to be aware that pixels on the edge of the image will not be kept.

If you want them to be of similar shapes, you can add the keyword "padding" and set its value to "same" when defining your Conv2D.

Here's what it's probably going to look like :

def MainEncoder():
    inp = Input(shape=(64,64,3))
    x = Conv2D(256,2, padding="same")(inp)
    x = MaxPool2D()(x)
    x = Conv2D(128,2, padding="same")(x)
    x = Flatten()(x)
    encoded = Dense(100,activation="relu")(x)

    encoder= Model(inp,encoded)
    return encoder

This padding will create what is effectively a black border on the outside of your image when the convolution is going through.

I hope I was useful

Related