Pytorch LSTM Multi Target Dimension Error

47 Views Asked by At

I've been trying for days to do an LSTM Multi Target without success, for a dataset with the first 8 columns being targets and the other columns features, generating dimension errors. The challenge consists of predicting 8 targets with integer values ​​that can be 0 or 1 or 2, based on the feature values. Previously I successfully created an LSTM that predicted a single target column, which was the sum of all 8 columns. But this sum generated undesirable results in the confidence score. What´s mistake?

import pandas as pd
import numpy as np

# Set seed for reproducibility
np.random.seed(42)

# Create DataFrame
data = {'col_' + str(i+1): np.random.choice([0, 1, 2], 100) if i < 8 else np.random.uniform(-0.99, 0.99, 100) for i in range(100)}
df = pd.DataFrame(data)
df.head()

# Display the DataFrame
print(df)

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# Extracting targets and features
targets = df.iloc[:, :8].values
features = df.iloc[:, 8:].values

# Scaling features
scaler = StandardScaler()
features = scaler.fit_transform(features)

# Convert targets to LongTensor
targets = torch.tensor(targets, dtype=torch.long)

# Convert features to FloatTensor
features = torch.tensor(features, dtype=torch.float32)

# Split the data into train and test sets
features_train, features_test, targets_train, targets_test = train_test_split(
    features, targets, test_size=0.2, random_state=None
)

# Create DataLoader
train_dataset = TensorDataset(features_train, targets_train)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)

# Define the LSTM model
class LSTMModel(nn.Module):
    def __init__(self, input_size, hidden_size, num_layers, output_size):
        super(LSTMModel, self).__init__()
        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):
        out, _ = self.lstm(x)
        out = self.fc(out[:, -1, :])
        return out

# Set hyperparameters
input_size = features.shape[1]
hidden_size = 64
num_layers = 2
output_size = 8  # Number of target classes
num_epochs = 10
learning_rate = 0.001

# Instantiate the model, loss function, and optimizer
model = LSTMModel(input_size, hidden_size, num_layers, output_size)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)

# Training loop
for epoch in range(num_epochs):
    for batch_features, batch_targets in train_loader:
        optimizer.zero_grad()
        outputs = model(batch_features)
        loss = criterion(outputs, batch_targets)
        loss.backward()
        optimizer.step()

    print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')

# Evaluate the model on the test set
model.eval()
with torch.no_grad():
    test_outputs = model(features_test)
    _, predicted = torch.max(test_outputs, 1)

# Calculate accuracy
correct = (predicted == targets_test).sum().item()
total = targets_test.size(0)
accuracy = correct / total
print(f'Test Accuracy: {accuracy:.4f}')

Runtime Error:

--------------------------------------------------------------------------- IndexError                                Traceback (most recent call last) Cell In[4], line 60 58 for batch_features, batch_targets in train_loader: 59     optimizer.zero_grad() ---> 60     outputs = model(batch_features) 61     loss = criterion(outputs, batch_targets) 62     loss.backward()

File c:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\torch\nn\modules\module.py:1501, in Module._call_impl(self, *args, **kwargs) 1496 # If we don't have any hooks, we want to skip the rest of the logic in 1497 # this function, and just call forward. 1498 if not (self._backward_hooks or self._backward_pre_hooks or self._forward_hooks or self._forward_pre_hooks 1499         or _global_backward_pre_hooks or _global_backward_hooks 1500         or _global_forward_hooks or _global_forward_pre_hooks): -> 1501     return forward_call(*args, **kwargs) 1502 # Do not call functions when jit is used 1503 full_backward_hooks, non_full_backward_hooks = [], []

Cell In[4], line 40 38 def forward(self, x): 39     out, _ = self.lstm(x) ---> 40     out = self.fc(out[:, -1, :]) 41     return out

IndexError: too many indices for tensor of dimension 2 

I try modify many times the Class LSTModel without a secure result

1

There are 1 best solutions below

0
Karl On

It looks like your input is a two dimensional tensor, while the LSTM module expects a three dimensional input. The input to nn.LSTM with batch_first=True should be of size (batch_size, sequence_length, input_size). See the documentation for more information.