keras/tests/manual/check_autoencoder.py
2015-08-18 16:49:31 -07:00

135 lines
5.4 KiB
Python

from __future__ import absolute_import
from __future__ import print_function
from keras.datasets import mnist
from keras.models import Sequential, model_from_config
from keras.layers.core import AutoEncoder, Dense, Activation, TimeDistributedDense, Flatten
from keras.layers.recurrent import LSTM
from keras.layers.embeddings import Embedding
from keras.layers.core import Layer
from keras.layers import containers
from keras.utils import np_utils
import numpy as np
nb_classes = 10
batch_size = 128
nb_epoch = 5
activation = 'linear'
input_dim = 784
hidden_dim = 392
max_train_samples = 5000
max_test_samples = 1000
# the data, shuffled and split between tran and test sets
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = X_train.reshape(60000, input_dim)[:max_train_samples]
X_test = X_test.reshape(10000, input_dim)[:max_test_samples]
X_train = X_train.astype("float32")
X_test = X_test.astype("float32")
X_train /= 255
X_test /= 255
# convert class vectors to binary class matrices
Y_train = np_utils.to_categorical(y_train, nb_classes)[:max_train_samples]
Y_test = np_utils.to_categorical(y_test, nb_classes)[:max_test_samples]
print("X_train: ", X_train.shape)
print("X_test: ", X_test.shape)
##########################
# dense model test #
##########################
print("Training classical fully connected layer for classification")
model_classical = Sequential()
model_classical.add(Dense(input_dim, 10, activation=activation))
model_classical.add(Activation('softmax'))
model_classical.get_config(verbose=1)
model_classical.compile(loss='categorical_crossentropy', optimizer='adam')
model_classical.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=False, verbose=0, validation_data=(X_test, Y_test))
classical_score = model_classical.evaluate(X_test, Y_test, verbose=0, show_accuracy=True)
print('\nclassical_score:', classical_score)
##########################
# autoencoder model test #
##########################
def build_lstm_autoencoder(autoencoder, X_train, X_test):
X_train = X_train[:, np.newaxis, :]
X_test = X_test[:, np.newaxis, :]
print("Modified X_train: ", X_train.shape)
print("Modified X_test: ", X_test.shape)
# The TimeDistributedDense isn't really necessary, however you need a lot of GPU memory to do 784x394-394x784
autoencoder.add(TimeDistributedDense(input_dim, 16))
autoencoder.add(AutoEncoder(encoder=LSTM(16, 8, activation=activation, return_sequences=True),
decoder=LSTM(8, input_dim, activation=activation, return_sequences=True),
output_reconstruction=False))
return autoencoder, X_train, X_test
def build_deep_classical_autoencoder(autoencoder):
encoder = containers.Sequential([Dense(input_dim, hidden_dim, activation=activation), Dense(hidden_dim, hidden_dim/2, activation=activation)])
decoder = containers.Sequential([Dense(hidden_dim/2, hidden_dim, activation=activation), Dense(hidden_dim, input_dim, activation=activation)])
autoencoder.add(AutoEncoder(encoder=encoder, decoder=decoder, output_reconstruction=False))
return autoencoder
# Try different things here: 'lstm' or 'classical' or 'denoising'
# or 'deep_denoising'
for autoencoder_type in ['classical', 'lstm']:
print(autoencoder_type)
print('-'*40)
# Build our autoencoder model
autoencoder = Sequential()
if autoencoder_type == 'lstm':
print("Training LSTM AutoEncoder")
autoencoder, X_train, X_test = build_lstm_autoencoder(autoencoder, X_train, X_test)
elif autoencoder_type == 'classical':
print("Training Classical AutoEncoder")
autoencoder = build_deep_classical_autoencoder(autoencoder)
else:
print("Error: unknown autoencoder type!")
exit(-1)
autoencoder.compile(loss='mean_squared_error', optimizer='adam')
# Do NOT use validation data with return output_reconstruction=True
autoencoder.fit(X_train, X_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=False, verbose=1)
# Do an inference pass
prefilter_train = autoencoder.predict(X_train, verbose=0)
prefilter_test = autoencoder.predict(X_test, verbose=0)
print("prefilter_train: ", prefilter_train.shape)
print("prefilter_test: ", prefilter_test.shape)
# Classify results from Autoencoder
print("Building classical fully connected layer for classification")
model = Sequential()
if autoencoder_type == 'lstm':
model.add(TimeDistributedDense(8, nb_classes, activation=activation))
model.add(Flatten())
elif autoencoder_type == 'classical':
model.add(Dense(prefilter_train.shape[1], nb_classes, activation=activation))
else:
model.add(Dense(prefilter_train.shape[1], nb_classes, activation=activation))
model.add(Activation('softmax'))
model.get_config(verbose=1)
model.compile(loss='categorical_crossentropy', optimizer='adam')
model.fit(prefilter_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=False, verbose=0, validation_data=(prefilter_test, Y_test))
score = model.evaluate(prefilter_test, Y_test, verbose=0, show_accuracy=True)
print('\nscore:', score)
print('Loss change:', (score[0] - classical_score[0])/classical_score[0], '%')
print('Accuracy change:', (score[1] - classical_score[1])/classical_score[1], '%')
# check serialization
config = autoencoder.get_config(verbose=1)
autoencoder = model_from_config(config)