Dimension reduction using Keras - python

I have a data set of MNIST hand written digits with 257 columns.
1 : 256 - pixel values
257 - target
How do I design an auto encoder using keras to reduce the input using 2 dimensions.
What I have tried
encoding_dim = 32
input_img = Input(shape=(256,))
encoded = Dense(encoding_dim, activation='relu')(input_img)
decoded = Dense(256, activation='sigmoid')(encoded)
# this model maps an input to its reconstruction
autoencoder = Model(input=input_img, output=decoded)
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')
autoencoder.fit(X, X,
nb_epoch=50,
batch_size=256,
shuffle=True)
Error
KeyError: '[318 327 ...] not in index

Related

LSTM Sequence as output of a neural network

I'm developing a neural network architecture that takes a vector as the input and outputs another different vector.
The error message I´m getting is the following:
ValueError: Dimensions must be equal, but are 384 and 96 for '{{node mean_squared_error/SquaredDifference}} = SquaredDifference[T=DT_FLOAT](sequential/cu_dnnlstm_1/transpose_1, IteratorGetNext:1)' with input shapes: [8,384,4], [8,96,4].
With regards to the code, I have declared the following training and validation vectors which shapes are:
x_train.shape = (96, 384, 21)
y_train.shape = (96, 96, 4)
x_val.shape = (25, 384, 21)
y_val.shape = (25, 96, 4)
Being "x" the input vector, and "y" the output vector, or the label of "x".
The architecture of the neural network is the following:
model = Sequential()
model.add(CuDNNLSTM(96,input_shape=(x_train.shape[1],x_train.shape[2]),return_sequences=True))
model.add(CuDNNLSTM(4,input_shape=(y_train.shape[1],y_train.shape[2]),return_sequences=True))
model.compile(optimizer=optimizer, loss='mse', metrics='mse')
Finally the fit of the neural network is done in the following lines:
# Fit the model
epochs = 10
batch_size = 8
train_steps = x_train.shape[0] // batch_size
valid_steps = x_val.shape[0] // batch_size
with tf.device("GPU:1"):
history = model.fit(x_train, y_train,
validation_data=(x_val, y_val),
epochs = epochs,
batch_size = batch_size,
steps_per_epoch = train_steps,
validation_steps = valid_steps,
callbacks=callbacks)
I dont understand where is the error, since in this dummy architecture both shapes match both the input and the output, I have seen that people usually make the output of the neural network a dense layer, but I would like it to be just the whole vector of "y" and not just a point.
Thanks in advance.
I have tried modifying the shapes that the LSTM layers use, doesnt work.

Why encoder part of Autoencoder can work without fitting?

Sample code from https://blog.keras.io/building-autoencoders-in-keras.html
import keras
from keras import layers
# This is our input image
input_img = keras.Input(shape=(784,))
# "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(784, 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,))
# 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))
autoencoder.compile(optimizer='adam', loss='binary_crossentropy')
autoencoder.fit(x_train, x_train,
epochs=50,
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)
In the example, only model autoencoder had been compiled and fitted, encoder is not.
I am so confused, why encoder can predict new data directly without any compiling and fitting?
encoder is a sub-model inside autoencoder (specifically, the part between input_img and encoded), it's not a separate model: you're just referring to a part of autoencoder with an explicit name.
When you train autoencoder, you're training both the encoder and decoder parts simultaneously. After training, encoder refers to the trained sub-model, that you can then use for inference.

Autoencoder and SVM implementation and improving AUC

Currently, I am using autoencoder to extract features from the fMRI images. I have a NumPy array of 9950 for each candidate and 4975 features are being extracted using autoencoder which is given SVM to predict if the candidate is suffering from a disease or not.
Here is my autoencoder model:
encoding_dim =4975
# this is our input placeholder
input_img = Input(shape=(9950,))
# "encoded" is the encoded representation of the input
encoded = Dense(encoding_dim, activation='relu')(input_img)
# "decoded" is the lossy reconstruction of the input
decoded = Dense(9950, activation='sigmoid')(encoded)
# this model maps an input to its reconstruction
autoencoder = Model(input_img, decoded)
print(autoencoder)
# 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))
import tensorflow as tf
from keras.optimizers import Adam,SGD
opt = SGD(lr=0.001)
autoencoder.compile(loss='binary_crossentropy', optimizer=opt, metrics=['AUC'])
While I am print the AUC which remains in 40-50 range. I want to improve my encoded features so that when I give it to the SVM for classification I should receive good accuracy. Any suggestions to improve the model?

Keras multi-output model wrongly calculate target dimensions: ValueError: Error when checking target

I'm trying to build a multi-output keras model starting from a working single output model. Keras however, is complaining about tensors dimensions.
The single output Model:
This GRU model is training and predicting fine:
timesteps = 250
features = 2
input_tensor = Input(shape=(timesteps, features), name="input")
conv = Conv1D(filters=128, kernel_size=6,use_bias=True)(input_tensor)
b = BatchNormalization()(conv)
s_gru, states = GRU(256, return_sequences=True, return_state=True, name="gru_1")(b)
biases = keras.initializers.Constant(value=88.15)
out = Dense(1, activation='linear', name="output")(s_gru)
model = Model(inputs=input_tensor, outputs=out)
My numpy arrays are:
train_x # shape:(7110, 250, 2)
train_y # shape: (7110, 250, 1)
If fit the model with the following code and everything is fine:
model.fit(train_x, train_y,batch_size=128, epochs=10, verbose=1)
The Problem:
I want to use a slightly modified version of the network that outputs also the GRU states:
input_tensor = Input(shape=(timesteps, features), name="input")
conv = Conv1D(filters=128, kernel_size=6,use_bias=True)(input_tensor)
b = BatchNormalization()(conv)
s_gru, states = GRU(256, return_sequences=True, return_state=True, name="gru_1")(b)
biases = keras.initializers.Constant(value=88.15)
out = Dense(1, activation='linear', name="output")(s_gru)
model = Model(inputs=input_tensor, outputs=[out, states]) # multi output
#fit the model but with a list of numpy array as y
model.compile(optimizer=optimizer, loss='mae', loss_weights=[0.5, 0.5])
history = model.fit(train_x, [train_y,train_y], batch_size=128, epochs=10, callbacks=[])
This training fails and keras is complaining about the target dimensions:
ValueError: Error when checking target: expected gru_1 to have 2 dimensions, but got array with shape (7110, 250, 1)
I'm using Keras 2.3.0 and Tensorflow 2.0.
What am I missing here?
The dimensions of the second output and the second element in the outputs list should be of similar shape. In this case, states would be of shape (7110, 256), which can't really be compared to the train_y shape (which will be of shape (7110, 250, 1) as noted in the first code block. Make sure the outputs can be compared with a similar shape.

ValueError: Error when checking input: expected lstm_1_input to have shape (973, 215) but got array with shape (61, 215)

I have received multiple diffrent ValueErrors when trying to solve following by changing many parameters.
It is a time series problem, I have data from 60 shops, 215 items, 1034 days. I have splitted 973 days for train and 61 for test.:
train_x = train_x.reshape((60, 973, 215))
test_x = test_x.reshape((60, 61, 215))
train_y = train_y.reshape((60, 973, 215))
test_y = test_y.reshape((60, 61, 215))
My model:
model = Sequential()
model.add(LSTM(100, input_shape=(train_x.shape[1], train_x.shape[2]),
return_sequences='true'))
model.add(Dense(215))
model.compile(loss='mean_squared_error', optimizer='adam', metrics=
['accuracy'])
history = model.fit(train_x, train_y, epochs=10,
validation_data=(test_x, test_y), verbose=2, shuffle=False)
ValueError: Error when checking input: expected lstm_1_input to have
shape (973, 215) but got array with shape (61, 215)
You've split your data with respect to timesteps as opposed to the samples. You need to decide on what are your samples in the first instance. For the sake of the answer I will assume these are along the first axis (assuming the data has been framed as a supervised time-series problem).
The input_size in LSTM expects the shape of (timesteps, data_dim) as explained here, and these dimensions must remain the same for each batch. In your example, samples from training and testing have different dimensions. The batch size can differ (unless specified with batch_size parameter).
Your data should be split between training and testing along the first axis. Here is an analogous example from Keras tutorials:
from keras.models import Sequential
from keras.layers import LSTM, Dense
import numpy as np
data_dim = 16
timesteps = 8
num_classes = 10
# expected input data shape: (batch_size, timesteps, data_dim)
model = Sequential()
model.add(LSTM(32, return_sequences=True,
input_shape=(timesteps, data_dim))) # returns a sequence of vectors of dimension 32
model.add(LSTM(32, return_sequences=True)) # returns a sequence of vectors of dimension 32
model.add(LSTM(32)) # return a single vector of dimension 32
model.add(Dense(10, activation='softmax'))
model.compile(loss='categorical_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
# Generate dummy training data
x_train = np.random.random((1000, timesteps, data_dim))
y_train = np.random.random((1000, num_classes))
# Generate dummy validation data
x_val = np.random.random((100, timesteps, data_dim))
y_val = np.random.random((100, num_classes))
model.fit(x_train, y_train,
batch_size=64, epochs=5,
validation_data=(x_val, y_val))
You will notice that timesteps is the same for training and testing data and x_train.shape[1] == x_val.shape[1]. It is the number of samples that differs along the first axis x_train.shape[0] is 1000 and x_val.shape[0] is 100.

Categories