0
votes

I have a task of predicting room occupancy(1,2) from 3 sensors using LSTM. See the image below for an example of this data:

data

import pandas as pd
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from sklearn.model_selection import train_test_split
import numpy as np
import matplotlib.pyplot as plt

x = np.array([
    [31, 3, 5],
    [32, 3, 5],
    [29, 0, 3],
    [31, 3, 4],
    [23, 2, 4],
    [22, 2, 4],
    [23, 1, 4], ])

y = np.array([
    [2],
    [2],
    [1],
    [2],
    [1],
    [1],
    [1], ])

x = x.reshape(7, 3, 1)

x_train,x_test,y_train,y_test = train_test_split(x, y,test_size =0.2, random_state = 4)

model=Sequential() 
model.add(LSTM((1), activation='softmax', input_shape=x_train.shape,return_sequences=False))

I got an error here:

--------------------------------------------------------------------------- ValueError Traceback (most recent call last) in ----> 1 model.add(LSTM((1), activation='softmax', input_shape=x_train.shape, return_sequences=False))

~/opt/anaconda3/lib/python3.7/site-packages/keras/engine/sequential.py in add(self, layer) 163 # and create the node connecting the current layer 164 # to the input layer we just created. --> 165 layer(x) 166 set_inputs = True 167 else:

~/opt/anaconda3/lib/python3.7/site-packages/keras/layers/recurrent.py in call(self, inputs, initial_state, constants, **kwargs) 530 531 if initial_state is None and constants is None: --> 532 return super(RNN, self).call(inputs, **kwargs) 533 534 # If any of initial_state or constants are specified and are Keras

~/opt/anaconda3/lib/python3.7/site-packages/keras/engine/base_layer.py in call(self, inputs, **kwargs) 412 # Raise exceptions in case the input is not compatible 413 # with the input_spec specified in the layer constructor. --> 414 self.assert_input_compatibility(inputs) 415 416 # Collect input shapes to build layer.

~/opt/anaconda3/lib/python3.7/site-packages/keras/engine/base_layer.py in assert_input_compatibility(self, inputs) 309 self.name + ': expected ndim=' + 310 str(spec.ndim) + ', found ndim=' + --> 311 str(K.ndim(x))) 312 if spec.max_ndim is not None: 313 ndim = K.ndim(x)

ValueError: Input 0 is incompatible with layer lstm_1: expected ndim=3, found ndim=4

Then I could not run the below few lines I have because of the error:

model.compile(loss='binary_crossentropy', optimizer='adam',metrics=['accuracy'])
model.summary()
history = model.fit(x_train, y_train, epochs=20, validation_data=(x_test, y_test))

Can anyone help me identify the problem? All data are categories converted into integers, is it reasonable to create the model in this way?

1

1 Answers

0
votes

You need to reshape your input like this:

x = x.reshape(x.shape[0], 1, x.shape[1])  # the 1 is the steps

And specify the input shape like this:

input_shape=(x.shape[1:])

So use these lines and it will work:

x = x.reshape(7, 1, 3)

model.add(LSTM((1), activation='softmax', input_shape=x_train.shape[1:],
    return_sequences=False))

Lastly, your activation function should be sigmoid if you have only two classes.