Matteo Sirizzotti
Matteo Sirizzotti

Reputation: 27

Multiclass classification LSTM keras

I'm stuck in writing keras code for multiclass classification problem. I will expose my problem.

I have a dataset in a single csv file which has rows in the following form

1.45    -10.09  1.02    1   0   0   0

the first 3 columns represent X,Y,Z accelerations that comes from an accelerometer. The last 4 columns represents class labels. I have 4 classes

[1 0 0 0][0 1 0 0][0 0 1 0][0 0 0 1]

each vector is a class label that correspond to a single gesture (shaking hand, rotate hand, lift hand, none-of-the-previous)

What i want is to have an LSTM that look back at the previous N steps (let's say 20) taking as input N 3D vectors [X,Y,Z] and at the end of each sequence (composed by these 20 3D vectors) spits out the probability of that sequence to belong to any of the four classes that i have.

Question1: From my understanding the model should be "many to one", am i right? Question2: how can i implement such network using keras API for python?

i'm really new in coding with keras and what i have done so far is this fragment of code (i'm working in colab):

    # load dataset
    from google.colab import files
    uploaded = files.upload()
    
    dataframe = pd.read_csv(io.BytesIO(uploaded['data_new.csv']), header=None)
    
  
    dataset = dataframe.values
    X = dataset[:,0:3].astype(float)
    Y = dataset[:,3:].astype(int)
    print(X.shape)
    print(Y.shape)
    model = Sequential()
    ...
    ...

the output of the print statements are:

(48886, 3)
(48886, 4)

I'll post here also some lines of the dataset:

1.45    -10.09  1.02    1   0   0   0   
1.06    -10.13  1.06    1   0   0   0   
1.22    -10.09  1.02    1   0   0   0   
1.38    -10.05  1.06    1   0   0   0   
1.03    -10.25  1.18    1   0   0   0   
0.04    -10.17  1.11    1   0   0   0   
0.55    -9.57   1.30    1   0   0   0   
1.18    -9.38   1.26    1   0   0   0   
2.36    -9.22   0.35    1   0   0   0
...
... 

do i have to reshape input in some way?i'm really stuck, please help me

EDIT I'm trying with the following code using the real dataset

dataframe = pd.read_csv(io.BytesIO(uploaded['data_new.csv']), header=None)

#dataframe = pandas.read_csv("iris.data", header=None)
dataset = dataframe.values
X = dataset[:,0:3].astype(float)
Y = dataset[:,3:].astype(int)

X_train = tf.expand_dims(X, axis=-1)


BATCH_SIZE = 20 
EPOCHS = 2 # Used less epochs for testing purposes

model = tf.keras.Sequential()
model.add(tf.keras.layers.LSTM(100, input_shape=(X_train.shape[1], X_train.shape[2])))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Dense(100, activation="relu"))
model.add(tf.keras.layers.Dense(4, activation="softmax"))
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
model.summary()
print("Fit the model on training data")
history = model.fit(X_train, Y, epochs=EPOCHS, batch_size=BATCH_SIZE, verbose=0)

sample_input = np.random.randint(0,100, size=(20, 3))
print(sample_input)
sample_input_reshaped = tf.expand_dims(sample_input, axis=1)
print(sample_input_reshaped.shape)
predictions = model.predict(sample_input_reshaped)
print('Model predictions', predictions)

and i am getting this error

ValueError: Input 0 is incompatible with layer sequential_11: expected shape=(None, None, 1), found shape=(None, 1, 3)

Upvotes: 0

Views: 1057

Answers (1)

yudhiesh
yudhiesh

Reputation: 6799

I made some dummy data based on the input shape of the data you have and ran the model that you would need for it. You can have a more complex model than this but for starters this is sufficient.

import pandas as pd
import tensorflow as tf
import numpy as np
from sklearn.model_selection import train_test_split

# Dummy data 
X = pd.DataFrame(np.random.randint(0, 100, size=(48886, 3)), columns=list("ABC"))
y = pd.DataFrame(np.random.randint(0, 2, size=(48886, 4)), columns=list("abcd"))
assert X.shape == (48886, 3)
assert y.shape == (48886, 4)

# You would just need to add the code below to yours
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, test_size=0.25)

X_train = tf.expand_dims(X_train, axis=1)
X_test = tf.expand_dims(X_test, axis=1)

BATCH_SIZE = 20 
EPOCHS = 2 # Used less epochs for testing purposes

model = tf.keras.Sequential()
model.add(tf.keras.layers.LSTM(100, input_shape=(X_train.shape[1], X_train.shape[2])))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Dense(100, activation="relu"))
model.add(tf.keras.layers.Dense(4, activation="softmax"))
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
model.summary()
print("Fit the model on training data")
history = model.fit(X_train, y_train, epochs=EPOCHS, batch_size=BATCH_SIZE, verbose=0)
print(f"History: {history.history}")
print("Evaluating on test data")
results = model.evaluate(X_test, y_test, batch_size=BATCH_SIZE)
print("test loss, test acc:", results)

sample_input = np.random.randint(0, 100, size=(20, 3))
sample_input_reshaped = tf.expand_dims(sample_input, axis=1)
predictions = model.predict(sample_input_reshaped)
print('Model predictions', predictions)
prediction_class = tf.argmax(predictions, axis=1)
print('Class of predictions', prediction_class)
most_frequent = np.bincount(prediction_class).argmax()
print('Most frequent class: ', most_frequent)

Output:

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
lstm (LSTM)                  (None, 100)               41600     
_________________________________________________________________
dropout (Dropout)            (None, 100)               0         
_________________________________________________________________
dense (Dense)                (None, 100)               10100     
_________________________________________________________________
dense_1 (Dense)              (None, 4)                 404       
=================================================================
Total params: 52,104
Trainable params: 52,104
Non-trainable params: 0
_________________________________________________________________
Fit the model on training data
2021-07-08 21:23:52.292396: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:176] None of the MLIR Optimization Passes are enabled (registered 2)
History: {'loss': [4.253803730010986, 7.2851409912109375], 'accuracy': [0.25578224658966064, 0.24983635544776917]}
Evaluating on test data
612/612 [==============================] - 1s 964us/step - loss: 15.3499 - accuracy: 0.2468
test loss, test acc: [15.3499116897583, 0.24676811695098877]
Model predictions [[6.8483874e-03 9.9284607e-01 3.0563556e-04 2.0347565e-08]
 [6.8483874e-03 9.9284607e-01 3.0563556e-04 2.0347565e-08]
 [6.8483874e-03 9.9284607e-01 3.0563556e-04 2.0347565e-08]
 [6.8483874e-03 9.9284607e-01 3.0563556e-04 2.0347565e-08]
 [6.8483874e-03 9.9284607e-01 3.0563556e-04 2.0347565e-08]
 [6.8483874e-03 9.9284607e-01 3.0563556e-04 2.0347565e-08]
 [6.8483874e-03 9.9284607e-01 3.0563556e-04 2.0347565e-08]
 [6.8483874e-03 9.9284607e-01 3.0563556e-04 2.0347565e-08]
 [6.8483874e-03 9.9284607e-01 3.0563556e-04 2.0347565e-08]
 [6.8483874e-03 9.9284607e-01 3.0563556e-04 2.0347565e-08]
 [6.8483874e-03 9.9284607e-01 3.0563556e-04 2.0347565e-08]
 [6.8483874e-03 9.9284607e-01 3.0563556e-04 2.0347565e-08]
 [6.8483874e-03 9.9284607e-01 3.0563556e-04 2.0347565e-08]
 [6.8483874e-03 9.9284607e-01 3.0563556e-04 2.0347565e-08]
 [6.8483874e-03 9.9284607e-01 3.0563556e-04 2.0347565e-08]
 [6.8483874e-03 9.9284607e-01 3.0563556e-04 2.0347565e-08]
 [6.8483874e-03 9.9284607e-01 3.0563556e-04 2.0347565e-08]
 [6.8483874e-03 9.9284607e-01 3.0563556e-04 2.0347565e-08]
 [6.7954701e-03 9.9290127e-01 3.0327393e-04 2.0033218e-08]
 [6.7954701e-03 9.9290127e-01 3.0327393e-04 2.0033218e-08]]
Class of predictions tf.Tensor([1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1], shape=(20,), dtype=int64)
Most frequent class: 1

Upvotes: 1

Related Questions