A Step-by-Step Guide to Classifying Multivariate Time Series with LSTM using PyTorch, PyTorch Lightning, and Python

Posted by


In this tutorial, we will walk you through how to perform multivariate time series classification using Long Short-Term Memory (LSTM) neural networks in PyTorch along with PyTorch Lightning framework in Python. We will cover the entire process from preprocessing the data, building the model, training, and evaluation.

Setting up the environment

First, make sure you have PyTorch and PyTorch Lightning installed in your Python environment. You can install the libraries using pip:

pip install torch torch-lightning

Next, import the necessary libraries:

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
from sklearn.preprocessing import StandardScaler
import numpy as np
import pandas as pd

Data Preparation

For this tutorial, we will use a sample multivariate time series dataset. You can use any dataset of your choice. Make sure that your dataset is in CSV format and contains multiple features along with the target variable.

Load the dataset into a Pandas DataFrame:

data = pd.read_csv('your_dataset.csv')

Next, convert the DataFrame into a numpy array:

data = data.to_numpy()

Now, split the data into input features and target variable:

X = data[:, :-1] # input features
y = data[:, -1] # target variable

Data Preprocessing

Normalize the input features using StandardScaler:

scaler = StandardScaler()
X = scaler.fit_transform(X)

Create DataLoader

Create a PyTorch DataLoader to feed the data into the model:

X = torch.tensor(X, dtype=torch.float)
y = torch.tensor(y, dtype=torch.long)

dataset = TensorDataset(X, y)
dataloader = DataLoader(dataset, batch_size=32, shuffle=True)

Building the LSTM model

Now, let’s build the LSTM model using PyTorch. Here is a simple implementation:

class LSTM(nn.Module):
    def __init__(self, input_size, hidden_size, num_layers, output_size):
        super(LSTM, self).__init__()

        self.hidden_size = hidden_size
        self.num_layers = num_layers
        self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
        self.fc = nn.Linear(hidden_size, output_size)

    def forward(self, x):
        h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)
        c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)

        out, _ = self.lstm(x, (h0, c0))

        out = self.fc(out[:, -1, :])

        return out

Training the model with PyTorch Lightning

We will train the model using PyTorch Lightning which simplifies the training loop. Here’s a sample code to train the model:

from pytorch_lightning import LightningModule, Trainer

class LSTMClassifier(LightningModule):
    def __init__(self, input_size, hidden_size, num_layers, output_size, lr=0.001):
        super(LSTMClassifier, self).__init__()

        self.model = LSTM(input_size, hidden_size, num_layers, output_size)
        self.criterion = nn.CrossEntropyLoss()
        self.lr = lr

    def forward(self, x):
        return self.model(x)

    def training_step(self, batch, batch_idx):
        x, y = batch
        y_hat = self.model(x)
        loss = self.criterion(y_hat, y)
        return loss

    def configure_optimizers(self):
        return optim.Adam(self.parameters(), lr=self.lr)

model = LSTMClassifier(input_size=X.shape[1], hidden_size=64, num_layers=1, output_size=2)
trainer = Trainer(max_epochs=10, gpus=1) # you can adjust the number of epochs and other parameters
trainer.fit(model, dataloader)

Evaluation

After training, you can evaluate the model on a separate test dataset. You can also use metrics such as accuracy, precision, recall, etc., to evaluate the model’s performance.

That’s it! You have successfully built a multivariate time series classification model using LSTM in PyTorch and PyTorch Lightning. Feel free to experiment with different architectures, hyperparameters, and datasets to improve the model’s performance.

0 0 votes
Article Rating
41 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
@mertmermerci218
2 months ago

Thank you for the insightful video! In this implementation we assume that all the instances in a sequence have the same label. What if the label of instances within a sequence are not the same and change within the sequence? How should we add the label information into the sequence?

@traderrider09
2 months ago

Hey, is it not necessary to temporally split the data while creating training and testing data sets?

@zakkyang6476
2 months ago

Hi, do you do the normalization before the modeling?

@anatolykruglov7991
2 months ago

благодаря) този урок е страхотен

@Artista1010
2 months ago

you can't shuffle time series 🙂

@user-oz3lm2ky5x
2 months ago

А по-русски не проще было рассказать?

@karthikr5884
2 months ago

Great video 🙂

@ErfanKhodabakhsh
2 months ago

please update the video code. many part of the code have bugs now

@zhuocao7459
2 months ago

ty!

@trueToastedCode
2 months ago

I achieved loss=0.4251 and sparse_categorical_accuracy: 0.8596 for my 20% splitted testing data. Used tensorflow convolution network instead – it also works much better on Apple Silico. It only trained for 5 minutes or so then EarlyStopping kicked in. Btw there is like 10% of the code needed to do to with keras compared to torch.

@banafsh4146
2 months ago

Thanks for this tutorial. Could you please make a video of how to work with multi dimensional arrays as training data for the mode?

@countrylifemoments4939
2 months ago

Hi, are you planning to share the code with Github?

@ProjectOfTheWeek
2 months ago

Don't work with CUDA 11.2 in google colab. Can update the code? thanks!

@sayederfanarefin
2 months ago

You explained each step very clearly. Thanks man!

@RedShipsofSpainAgain
2 months ago

15:41: Making the PTL LightningDataModule.
20:04: Making the SequenceModel, which extends Pytorch nn.Module.
23:40: Making the PTL LightningModule.

@elizabethm.j139
2 months ago

Could you pls explain it using tensorflow?

@karlbooklover
2 months ago

I'm getting this error:
TypeError: can't convert cuda:0 device type tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first.

Would you mind sharing the source code? That would help a lot

@renukalra7537
2 months ago

can we one-hot encode the categorical variables?

@anonproxy6235
2 months ago

Awesome video mate. Do you have one on timeseries classification with MLP?