0
$\begingroup$

I am trying to load 2 images to an autoencoder but for some reason, it does not rebuild the input image.

An autoencoder is supposed to compress and decompress an image. However, when passing two images with which it trains, it only shows a black color instead of the corresponding image.

import keras
from keras import layers

# This is the size of our encoded representations
encoding_dim = 32  # 32 floats -> compression of factor 24.5, assuming the input is 784 floats

#28*28=784  tamaño de images de nmist


ancho=28
alto=28
n_pixels=alto*ancho

# This is our input image
input_img = keras.Input(shape=(n_pixels,))

# "encoded" is the encoded representation of the input
encoded = layers.Dense(encoding_dim, activation='relu')(input_img)
# "decoded" is the lossy reconstruction of the input
decoded = layers.Dense(n_pixels, activation='sigmoid')(encoded)


# This model maps an input to its reconstruction
autoencoder = keras.Model(input_img, decoded)

# This model maps an input to its encoded representation
encoder = keras.Model(input_img, encoded)




# This is our encoded (32-dimensional) input
encoded_input = keras.Input(shape=(encoding_dim,))#la salid del encoder osea la entrada del decoder
# Retrieve the last layer of the autoencoder model
decoder_layer = autoencoder.layers[-1]
# Create the decoder model
decoder = keras.Model(encoded_input, decoder_layer(encoded_input))

This code is to load two images with the help of pil module:

##load custom data
from PIL import Image
import numpy as np

#data1=np.linspace(0,0,2)
#data1_test=np.linspace(0,0,2)
data1=[0,0,0]
data1_test=[0,0,0]

data2=np.linspace(0,0,n_pixels*2).reshape(2,n_pixels)


data1[0]=Image.open("/content/zero.png")
data1[1]=Image.open("/content/eight.png")

#custom_imagen_arr=np.array(list(custom_imagen)[0]).reshape(1,784)
custom_data_arr=np.linspace(0,0,n_pixels*2).reshape(2,n_pixels)
for  i2 in range(2):
       imm=list(data1[i2].getdata())
       for  i in range(len(list(data1[i2].getdata()))):
            custom_data_arr[1,i]=imm[i][0] / 255.
       for  i in range(len(list(data1[i2].getdata()))):
            data2[i2][i]=custom_data_arr[1,i]
data2 = data2.astype('float32') / 255.

data2 = data2.reshape((len(data2), np.prod(data2.shape[1:])))

Then I train:

autoencoder.compile(optimizer='adam', loss='binary_crossentropy')
import numpy as np
autoencoder.fit(data2, data2,
                epochs=152,
                batch_size=1,
                verbose=1,
                validation_data=(data2, data2))

After finishing training, I choose one of the loaded images and make a prediction, but the output is black.

#give an arbitrary image to the autoencoder and generate an image

from PIL import Image
custom_imagen=Image.open("/content/eight.png")
#custom_imagen_arr=np.array(list(custom_imagen)[0]).reshape(1,784)
custom_imagen_arr=np.linspace(1,0,n_pixels*2).reshape(2,n_pixels)
imm=list(custom_imagen.getdata())
for  i in range(len(list(custom_imagen.getdata()))):
        custom_imagen_arr[1,i]=imm[i][0] / 255.
encoded_imgs = encoder.predict(custom_imagen_arr)
decoded_imgs = decoder.predict(encoded_imgs)

# Use Matplotlib (don't ask)
import matplotlib.pyplot as plt

n = 2  # How many digits we will display
plt.figure(figsize=(20, 4))
for i in range(n):
    # Display original
    ax = plt.subplot(2, n, i + 1)
    plt.imshow(custom_imagen_arr[i].reshape(alto, ancho))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)

    # Display reconstruction
    ax = plt.subplot(2, n, i + 1 + n)
    plt.imshow(decoded_imgs[i].reshape(alto, ancho))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
plt.show()

How do I so that the output of the autoencoder is not black and the same number is the one I train?

The code is modified from here.

$\endgroup$

2 Answers 2

0
$\begingroup$

I'm doing the same thing actually. I had to find tools because I was getting black images too.

This one worked for me:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvas
from PIL import Image
import tensorflow as tf

keras_imager = tf.keras.preprocessing.image

# creating a figure to plot data
fig = Figure(figsize=(3, 2), dpi=96) # adjust your params
canvas = FigureCanvas(fig)
ax = fig.add_subplot(111)

# plot the data
ax.plot(your_data)

# draw the canvas, cache the renderer
canvas.draw()       
s, (width, height) = canvas.print_to_buffer()

# converting to a NumPy array.
X = np.frombuffer(s, np.uint8).reshape((height, width, 4))

# converting to 3D rgb array data
img = keras_imager.array_to_img(X)
rgb = img.convert('RGB')
arr = keras_imager.img_to_array(rgb)
# standardize each image 
arr = tf.image.per_image_standardization(arr)

# If you want to resize
arr = tf.image.resize(arr, (32, 32), # <- adjust your param
                     preserve_aspect_ratio=True)
# you can view the keras transformed plot 
keras_imager.array_to_img(rgb)

Honestly, I don't quite understand all the parameters, but it's the simplest way I could tweak it to work for my situation. Good luck.

$\endgroup$
0
$\begingroup$

Activation functions required for your task depends on the normalization of your data. For example if you were to use MNIST (pixel values are between 0 and 1 ) then you would need to use sigmoid for both encoder and decoder. However if your input image is not normalized as MNIST then you would need Relu activation after encoder and sigmoid after decoder. This rule is not certain but it is like a general idea.

You can try to normalize the data and switch your activation functions.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.