Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Too strong regularization for an autoencoder (Keras autoencoder tutorial code)

I'm using this tutorial about autoencoders: https://blog.keras.io/building-autoencoders-in-keras.html

All the code is working, however the performance is very bad (the results are blurred) when I set 10e-5 for the regularization parameter, which is the parameter defined in the tutorial code. In fact, I need to decrease the regularization to 10e-8 to have a correct output.

My question is as follows: Why the result is so different from the tutorial? Data is the same and parameters are the same, I didn't expect a large difference.

I suspect that the default behavior of the Keras functions has been changed (automatic batch normalization performed in all cases?) from May 14th, 2016.

Outputs

Link to the blurred image output with 10e-5 regularization

  • With 10e-5 regularization (blurred); val_loss of 0.2967 after 50 epochs and 0.2774 after 100 epochs.
  • With 10e-8 regularization: val_loss of 0.1080 after 50 epochs and 0.1009 after 100 epochs.
  • With no regularization: val_loss of 0.1018 after 50 epochs and 0.0944 after 100 epochs.

Complete code (for reference)

# Source: https://blog.keras.io/building-autoencoders-in-keras.html
import numpy as np
np.random.seed(2713)

from keras.layers import Input, Dense
from keras.models import Model
from keras import regularizers

encoding_dim = 32

input_img = Input(shape=(784,))
# add a Dense layer with a L1 activity regularizer
encoded = Dense(encoding_dim, activation='relu',
                activity_regularizer=regularizers.l1(10e-5))(input_img)
decoded = Dense(784, activation='sigmoid')(encoded)

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))

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

from keras.datasets import mnist
(x_train, _), (x_test, _) = mnist.load_data()

x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.
x_train = x_train.reshape((len(x_train), np.prod(x_train.shape[1:])))
x_test = x_test.reshape((len(x_test), np.prod(x_test.shape[1:])))
print(x_train.shape)
print(x_test.shape)

autoencoder.fit(x_train, x_train,
                epochs=100,
                batch_size=256,
                shuffle=True,
                validation_data=(x_test, x_test))

# encode and decode some digits
# note that we take them from the *test* set
encoded_imgs = encoder.predict(x_test)
decoded_imgs = decoder.predict(encoded_imgs)

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

n = 10  # 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(x_test[i].reshape(28, 28))
    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(28, 28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
plt.show()
like image 775
ahstat Avatar asked Apr 27 '17 12:04

ahstat


1 Answers

I have the same issue. And it is on GitHub here https://github.com/keras-team/keras/issues/5414 It seems like you were correct in just changing the constant.

like image 180
SP67 Avatar answered Oct 17 '22 19:10

SP67