Keras LSTM input features and incorrect dimensional data input - machine-learning

So I'm trying to practice how to use LSTMs in Keras and all parameter (samples, timesteps, features). 3D list is confusing me.
So I have some stock data and if the next item in the list is above the threshold of 5 which is +-2.50 it buys OR sells, if it is in the middle of that threshold it holds, these are my labels: my Y.
For my features my X I have a dataframe of [500, 1, 3] for my 500 samples and each timestep is 1 since each data is 1 hour increment and 3 for 3 features. But I get this error:
ValueError: Error when checking model input: expected lstm_1_input to have 3 dimensions, but got array with shape (500, 3)
How can I fix this code and what am I doing wrong?
import json
import pandas as pd
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
"""
Sample of JSON file
{"time":"2017-01-02T01:56:14.000Z","usd":8.14},
{"time":"2017-01-02T02:56:14.000Z","usd":8.16},
{"time":"2017-01-02T03:56:15.000Z","usd":8.14},
{"time":"2017-01-02T04:56:16.000Z","usd":8.15}
"""
file = open("E.json", "r", encoding="utf8")
file = json.load(file)
"""
If the price jump of the next item is > or < +-2.50 the append 'Buy or 'Sell'
If its in the range of +- 2.50 then append 'Hold'
This si my classifier labels
"""
data = []
for row in range(len(file['data'])):
row2 = row + 1
if row2 == len(file['data']):
break
else:
difference = file['data'][row]['usd'] - file['data'][row2]['usd']
if difference > 2.50:
data.append((file['data'][row]['usd'], 'SELL'))
elif difference < -2.50:
data.append((file['data'][row]['usd'], 'BUY'))
else:
data.append((file['data'][row]['usd'], 'HOLD'))
"""
add the price the time step which si 1 and the features which is 3
"""
frame = pd.DataFrame(data)
features = pd.DataFrame()
# train LSTM
for x in range(500):
series = pd.Series(data=[500, 1, frame.iloc[x][0]])
features = features.append(series, ignore_index=True)
labels = frame.iloc[16000:16500][1]
# test
#yt = frame.iloc[16500:16512][0]
#xt = pd.get_dummies(frame.iloc[16500:16512][1])
# create LSTM
model = Sequential()
model.add(LSTM(3, input_shape=features.shape, activation='relu', return_sequences=False))
model.add(Dense(2, activation='relu'))
model.add(Dense(1, activation='relu'))
model.compile(loss='mse', optimizer='adam', metrics=['accuracy'])
model.fit(x=features.as_matrix(), y=labels.as_matrix())
"""
ERROR
Anaconda3\envs\Final\python.exe C:/Users/Def/PycharmProjects/Ether/Main.py
Using Theano backend.
Traceback (most recent call last):
File "C:/Users/Def/PycharmProjects/Ether/Main.py", line 62, in <module>
model.fit(x=features.as_matrix(), y=labels.as_matrix())
File "\Anaconda3\envs\Final\lib\site-packages\keras\models.py", line 845, in fit
initial_epoch=initial_epoch)
File "\Anaconda3\envs\Final\lib\site-packages\keras\engine\training.py", line 1405, in fit
batch_size=batch_size)
File "\Anaconda3\envs\Final\lib\site-packages\keras\engine\training.py", line 1295, in _standardize_user_data
exception_prefix='model input')
File "\Anaconda3\envs\Final\lib\site-packages\keras\engine\training.py", line 121, in _standardize_input_data
str(array.shape))
ValueError: Error when checking model input: expected lstm_1_input to have 3 dimensions, but got array with shape (500, 3)
"""
Thanks.

This is my first post here I wish that could be useful I will try to do my best
First you need to create 3 dimension array to work with input_shape in keras you can watch this in keras documentation or in a better way:
from keras.models import Sequential
Sequential?
Linear stack of layers.
Arguments
layers: list of layers to add to the model.
# Note
The first layer passed to a Sequential model
should have a defined input shape. What that
means is that it should have received an input_shape
or batch_input_shape argument,
or for some type of layers (recurrent, Dense...)
an input_dim argument.
Example
```python
model = Sequential()
# first layer must have a defined input shape
model.add(Dense(32, input_dim=500))
# afterwards, Keras does automatic shape inference
model.add(Dense(32))
# also possible (equivalent to the above):
model = Sequential()
model.add(Dense(32, input_shape=(500,)))
model.add(Dense(32))
# also possible (equivalent to the above):
model = Sequential()
# here the batch dimension is None,
# which means any batch size will be accepted by the model.
model.add(Dense(32, batch_input_shape=(None, 500)))
model.add(Dense(32))
After that how to transform arrays 2 dimensions in 3 dimmension
check np.newaxis
Useful commands that help you more than you expect:
Sequential?,
-Sequential??,
-print(list(dir(Sequential)))
Best

Related

How to update the output of activation function after each batch ends, using Keras?

If I want after each batch ends to update the output activation of a specific layer, How can I do that in Keras?
For example, the output shape of a specific layer= [9,1500], where 9 is the batch size and 1500 is the output features. How can I update this output after each batch ends ?
This is my model architecture:
from keras.models import Sequential,Model
from keras.layers import Input,Embedding,Conv1D,Multiply,Activation,MaxPooling1D,Dense,Flatten
vocab_size=467
outPut_dimention=8
sequence_length=429278
main_input = Input(shape=(sequence_length,), name='main_input')
embedding_layer=Embedding(vocab_size+1,outPut_dimention,input_length=sequence_length)(main_input)
one_D_conv_layer1=Conv1D(128,32,strides=32 , activation='sigmoid' )(embedding_layer)
one_D_conv_layer2=Conv1D(128,32,strides=32, name="conv1d")(embedding_layer)
merge=Multiply()([one_D_conv_layer1,one_D_conv_layer2])
max_pooling=MaxPooling1D(pool_size=400)(merge)
flat_layer=Flatten()(max_pooling)
fully_connected=Dense(128)(flat_layer)
main_output=Dense(9, activation='softmax')(fully_connected)
model=Model(inputs=[main_input], outputs=[main_output])
model.compile(loss='categorical_crossentropy',
optimizer="Nadam",
metrics=['accuracy'])
history1=model.fit_generator(generator=training_generator,
validation_data=validation_generator,
use_multiprocessing=True,
workers=6,
epochs=1,callbacks=[myCallBack])
What I want to do is that during the training process, I want to update the out put of the fully_connected layer at the end of each batch. For example, if the output of the fully_connected layer is a numpy array of shape (?, 128), where ? is the batch size, then I want to update that numpy array at the end of each batch.
I found on Keras official website link a way to define your costume regularization under the section "Developing new regularizers". Since I need to have an access to layer output (batch_size,n_nodes), then I need to define a custom activity_regularizer.
from keras import backend as K
class Regularizer(object):
"""Regularizer base class.
"""
def __call__(self, x):
return 0.
#classmethod
def from_config(cls, config):
return cls(**config)
class DeCovRegularizer(Regularizer):
# def set_layer(self, layer):
# self.layer = layer
def __call__(self, x):
# print(x.shape)
# x will be the output of the layer: (batch_size,n_nodes)
# means=[u1,u2,u3,u4,....] : where u1 is the (sum of node1 over the batch size)/batch_size
means=(K.sum(x,axis=0)/batch_size) #axis=0 to sum over the column not the rows
sub_mean=x-means # we subtract the mean from the nodes; for Example, node1-u1, node2-u2 ......
node_numbers=x.shape[1] # in our example it will be 128
# Constructing the C matrix; however it will be 1Dim=[c1_2,c1_3....c1_n,c2_1,c2_3......,c2_d.......]
C=K.variable(np.array([0])) # initialize C with 0 --> C=[0]
for i in range (0,node_numbers):
for j in range(0,node_numbers):
if(i !=j):
C_i_j=K.sum(sub_mean[:,i]*sub_mean[:,j],keepdims=True)
C=K.concatenate([C, C_i_j], axis=-1)
DecovLoss=K.sum(C*C)/0.5
return DecovLoss
# def get_config(self):
# return {"name": self.__class__.__name__,
# "p": self.l1}
in my model I added the Decov loss as following :
fully_connected=Dense(128,activity_regularizer=DeCovRegularizer())(flat_layer)
Just to make sure, during the training process the returned value by the call function will be added to the main loss (cross entropy), right? so that the Decov loss will be added automatically to the cross entropy loss, is that right? Am I implementing the DeCov loss correctly ?

Keras:Unable to add Dense layer to VGG16

I am trying to fine-tune the last convolution block of vgg16 (imagenet pretrained) with a few dense layers added on top. My code is below. I am not able to figure out why I get this error upon execution Error when checking target: expected sequential_9 to have shape (None, 11) but got array with shape (4, 1). The number of classes in my dataset is 11 and the batch size is 4. Am I somehow mixing these two? Please help.
def finetune( epochs):
num_classes = 11
batch_size = 4
base_model = VGG16(weights='imagenet', include_top=False, input_shape = (224,224,3))
print('Model loaded.')
print(base_model.output_shape[1:])
top_model = Sequential()
top_model.add(Flatten(input_shape=base_model.output_shape[1:]))
top_model.add(Dense(512, activation='relu',kernel_regularizer=regularizers.l2(0.01)))
top_model.add(Dropout(0.25))
top_model.add(Dense(256, activation='relu', kernel_regularizer=regularizers.l2(0.01)))
top_model.add(Dropout(0.25))
top_model.add(Dense(num_classes, activation='softmax'))
top_model.load_weights('vgg_ft_best.h5')
# add the model on top of the convolutional base
#model = Model(inputs= base_model.input, outputs= top_model(base_model.output))
#base_model.add(top_model)
#print(base_model.summary())
new_model = Sequential()
for l in base_model.layers:
new_model.add(l)
# CONCATENATE THE TWO MODELS
new_model.add(top_model)
print(new_model.summary())
# set the first 10 layers (up to the last conv block)
# to non-trainable (weights will not be updated)
for layer in new_model.layers[:11]:
layer.trainable = False
# prepare data augmentation configuration
train_datagen = ImageDataGenerator(
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
train_data_dir = "./images/train"
validation_data_dir = "./images/validation"
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(224, 224),
batch_size=batch_size,
class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(224, 224),
batch_size=batch_size,
class_mode='binary')
num_train_samples = len(train_generator.filenames)
num_validation_samples = len(validation_generator.filenames)
print(num_validation_samples)
new_model.compile(loss='categorical_crossentropy',
optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
metrics=['accuracy'])
# fine-tune the model
new_model.fit_generator(
train_generator,
steps_per_epoch=int(num_train_samples/batch_size),
epochs=epochs,
validation_data=validation_generator,
validation_steps = int(num_validation_samples/batch_size))
The problem is your data (target = true outputs, true labels, etc.).
Your target has shape (batch,1), and your model with 11 classes is expecting (batch,11)
So, the problem lies in your generator. It must output tensors with 11 classes.
For that, see the documentation for flow_from_directory and the highlighted parts:
classes: optional list of class subdirectories (e.g. ['dogs', 'cats']). Default: None. If not provided, the list of classes will be automatically inferred from the subdirectory names/structure under directory, where each subdirectory will be treated as a different class (and the order of the classes, which will map to the label indices, will be alphanumeric). The dictionary containing the mapping from class names to class indices can be obtained via the attribute class_indices.
class_mode: one of "categorical", "binary", "sparse", "input" or None. Default: "categorical". Determines the type of label arrays that are returned: "categorical" will be 2D one-hot encoded labels, "binary" will be 1D binary labels, "sparse" will be 1D integer labels, "input" will be images identical to input images (mainly used to work with autoencoders). If None, no labels are returned (the generator will only yield batches of image data, which is useful to use model.predict_generator(), model.evaluate_generator(), etc.). Please note that in case of class_mode None, the data still needs to reside in a subdirectory of directory for it to work correctly.
Solution
You need to dispose your images in 11 different folders, each folder being a different class.
You need to use class_mode='categorical' to have the (batch,11) format.
Now, if your classes are not categorical (one image can have two or more classes), then you need to create your own custom generator.

Why different intermediate layer ouput of CNN in keras?

I am using this code to perform some experiment, I want to use intermediate layer representation of layer mainly before the fully connected layer(or last layer) of CNN.
from __future__ import print_function
from keras.preprocessing import sequence
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
from keras.layers import Embedding
from keras.layers import Conv1D, GlobalMaxPooling1D
from keras.datasets import imdb
# set parameters:
max_features = 5000
maxlen = 400
batch_size = 100
embedding_dims = 50
filters = 250
kernel_size = 3
hidden_dims = 250
epochs = 100
print('Loading data...')
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features)
print(len(x_train), 'train sequences')
print(len(x_test), 'test sequences')
print('Pad sequences (samples x time)')
x_train = sequence.pad_sequences(x_train, maxlen=maxlen)
x_test = sequence.pad_sequences(x_test, maxlen=maxlen)
print('x_train shape:', x_train.shape)
print('x_test shape:', x_test.shape)
print('Build model...')
model = Sequential()
# we start off with an efficient embedding layer which maps
# our vocab indices into embedding_dims dimensions
model.add(Embedding(max_features,
embedding_dims,
input_length=maxlen))
model.add(Dropout(0.2))
# we add a Convolution1D, which will learn filters
# word group filters of size filter_length:
model.add(Conv1D(filters,
kernel_size,
padding='valid',
activation='relu',
strides=1))
# we use max pooling:
model.add(GlobalMaxPooling1D())
# We add a vanilla hidden layer:
model.add(Dense(hidden_dims))
model.add(Dropout(0.2))
model.add(Activation('relu'))#<======== I need output after this.
# We project onto a single unit output layer, and squash it with a sigmoid:
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.compile(loss='binary_crossentropy',
optimizer='adam', metrics=['accuracy'])
To get the intermediate layer representation of penultimate layer I used following code.
CODE1
get_layer_output = K.function([model.layers[0].input, K.learning_phase()],
[model.layers[6].output])
# output in test mode = 0
layer_output_test = get_layer_output([x_test, 0])[0]
# output in train mode = 1
layer_output_train = get_layer_output([x_train, 1])[0]
print(layer_output_train)
print(layer_output_train.shape)
CODE2
def get_activations(model, layer, X_batch):
get_activations = K.function([model.layers[0].input, K.learning_phase()], [model.layers[layer].output,])
activations = get_activations([X_batch,1])
return activations
import numpy as np
X_train=np.array(get_activations(model=model,layer=6, X_batch=x_train)[0], dtype=np.float32)
print(X_train)
print(X_train.shape)
Which one is correct as I am getting/printing different output for above two codes? I want to use the above correct output to multiply by weights and optimise by custom optimiser.
If you pass 1 to K.learning_phase() you will get different results every time. But both codes give the same result.
Using a higher level approach, you can do this:
from keras.models import Model
newModel = Model(model.inputs,model.layers[6].output)
Do whatever you want with newModel. You can train it (and affect the original model), and use it to predict values.

How to make one layer output two layer, and one layer connected to two layers in Keras?

I want to make a model in Keras, some connections of layers like this:
MaxPooling
/\
/ \
pooled poolmask convLayer
\ /
\ /
upsample
This type of connection is as Segnet, and it's easy to do in Caffe. But I don't know how to implement with keras.
Anybody could help me?
It's easy in Keras too, but you need to use Keras Functional API.
Here you can find an example https://keras.io/getting-started/functional-api-guide/
And the code:
from keras.layers import Input, Embedding, LSTM, Dense
from keras.models import Model
# Headline input: meant to receive sequences of 100 integers, between 1 and 10000.
# Note that we can name any layer by passing it a "name" argument.
main_input = Input(shape=(100,), dtype='int32', name='main_input')
# This embedding layer will encode the input sequence
# into a sequence of dense 512-dimensional vectors.
x = Embedding(output_dim=512, input_dim=10000, input_length=100)(main_input)
# A LSTM will transform the vector sequence into a single vector,
# containing information about the entire sequence
lstm_out = LSTM(32)(x)
auxiliary_input = Input(shape=(5,), name='aux_input')
x = keras.layers.concatenate([lstm_out, auxiliary_input])
auxiliary_output = Dense(1, activation='sigmoid', name='aux_output')(lstm_out)
# We stack a deep densely-connected network on top
x = Dense(64, activation='relu')(x)
x = Dense(64, activation='relu')(x)
x = Dense(64, activation='relu')(x)
# And finally we add the main logistic regression layer
main_output = Dense(1, activation='sigmoid', name='main_output')(x)
model = Model(inputs=[main_input, auxiliary_input], outputs=[main_output, auxiliary_output])
model.compile(optimizer='rmsprop', loss='binary_crossentropy',
loss_weights=[1., 0.2])
model.fit([headline_data, additional_data], [labels, labels],
epochs=50, batch_size=32)

TensorFlow - Classification with thousands of labels

I'm very new to TensorFlow. I've been trying use TensorFlow to create a function where I give it a vector with 6 features and get back a label.
I have a training data set in the form of 6 features and 1 label. The label is in the first column:
309,3,0,2,4,0,6
309,12,0,2,4,0,6
309,0,4,17,2,0,6
318,0,660,414,58,3,12
311,0,0,414,58,0,2
298,0,53,355,5,0,2
60,16,14,381,30,4,2
312,0,8,8,13,0,3
...
I have the index for the labels which is a list of thousand and thousands of names:
309,Joe
318,Joey
311,Bruce
...
How do I create a model and train it using TensorFlow to be able to predict the label, given a vector without the first column?
--
This is what I tried:
from __future__ import print_function
import tflearn
name_count = sum(1 for line in open('../../names.csv')) # this comes out to 24260
# Load CSV file, indicate that the first column represents labels
from tflearn.data_utils import load_csv
data, labels = load_csv('../../data.csv', target_column=0,
categorical_labels=True, n_classes=name_count)
# Build neural network
net = tflearn.input_data(shape=[None, 6])
net = tflearn.fully_connected(net, 32)
net = tflearn.fully_connected(net, 32)
net = tflearn.fully_connected(net, 2, activation='softmax')
net = tflearn.regression(net)
# Define model
model = tflearn.DNN(net)
# Start training (apply gradient descent algorithm)
model.fit(data, labels, n_epoch=10, batch_size=16, show_metric=True)
# Predict
pred = model.predict([[218,5,124,26,0,3]]) # 326
print("Name:", pred[0][1])
It's based on https://github.com/tflearn/tflearn/blob/master/tutorials/intro/quickstart.md
I get the error:
ValueError: Cannot feed value of shape (16, 24260) for Tensor u'TargetsData/Y:0', which has shape '(?, 2)'
24260 is the number of lines in names.csv
Thank you!
net = tflearn.fully_connected(net, 2, activation='softmax')
looks to be saying you have 2 output classes, but in reality you have 24260. 16 is the size of your minibatch, so you have 16 rows of 24260 columns (one of these 24260 will be a 1, the others will be all 0s).

Resources