Reputation: 27
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
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