UserWarning: RNN module weights are not part of single contiguous chunk of memory

47 Views Asked by At

Was working on a Siamese LSTM model for classification, undertook this project to understand the implementation and working of it. The model runs well on CPU but when I try to shift it to GPU, this error pops

# Check if CUDA is available
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# Define the Siamese LSTM model
class SiameseLSTM(nn.Module):
    def __init__(self, input_size, hidden_size, num_layers, num_classes):
        super(SiameseLSTM, self).__init__()
        self.encoder = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
        self.fc = nn.Linear(hidden_size, num_classes)  # Output layer with num_classes units

    def forward(self, x1, x2):
        out1, _ = self.encoder(x1)
        out1 = out1[:, -1, :]  
        out2, _ = self.encoder(x2) 
        out2 = out2[:, -1, :]  
        out1 = F.softmax(self.fc(out1), dim=1)  
        out2 = F.softmax(self.fc(out2), dim=1)  
        return out1, out2



class CSVDataset(Dataset):
    def __init__(self, folder_path, transform=None):
        self.folder_path = folder_path
        self.transform = transform
        self.file_paths = [os.path.join(folder_path, file) for file in os.listdir(folder_path) if file.endswith('.csv')]
        self.labels = [self.extract_label(file) for file in self.file_paths]  # Extract labels from file names

    def __len__(self):
        return len(self.file_paths)

    def extract_label(self, file_name):
        if 'wheat' in file_name:
            return 1
        elif 'mustard' in file_name:
            return 2
        elif 'sugarcane' in file_name:
            return 3
        else:
            return 0  # If none of the keywords are present, assign label 0

    def __getitem__(self, idx):
        data = pd.read_csv(self.file_paths[idx])
        if 'feature_index' in data.columns:
            data.drop(columns=['feature_index'], inplace=True)

        
        if self.transform:
            data = self.transform(data)

        label = self.labels[idx]
        return data, label

    def collate_fn(self, batch):
        
        padded_batch = [seq.clone().detach() for seq, _ in batch]
        padded_batch = pad_sequence(padded_batch, batch_first=True, padding_value=0.0)
        labels = [label for _, label in batch]
        return padded_batch, labels

# Custom transform function to convert data to PyTorch tensors
def transform_fn(data):
    
    if 'date' in data.columns:
        data.drop(columns=['date'], inplace=True)

    
    data_tensor = torch.tensor(data.values, dtype=torch.float32)
    return data_tensor

folder_path = r'E:\project_data\final data'
dataset = CSVDataset(folder_path, transform=transform_fn)

# Split the dataset into training and testing sets
train_indices, test_indices = train_test_split(list(range(len(dataset))), test_size=0.2, random_state=42)

# Create Subset objects for train and test datasets
train_dataset = Subset(dataset, train_indices)
test_dataset = Subset(dataset, test_indices)

# Define data loaders
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True, collate_fn=dataset.collate_fn)
test_loader = DataLoader(test_dataset, batch_size=64, collate_fn=dataset.collate_fn)

# Hyperparameters
input_size = len(train_dataset[0][0])  
hidden_size = 128
num_layers = 20
num_classes = len(set(dataset.labels))  

# Model, loss, optimizer
model = SiameseLSTM(input_size, hidden_size, num_layers, num_classes).to(device)
model.encoder.flatten_parameters()  
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)


# Training loop
num_epochs = 10
for epoch in range(num_epochs):
    model.train()  # Set the model to training mode
    running_loss = 0.0
    for data, labels in train_loader:
        data, labels = data.to(device), torch.tensor(labels).to(device)  # Move data to the GPU
        optimizer.zero_grad()
        outputs1, outputs2 = model(data[:, 0, :, None], data[:, 1, :, None])
        
        # Convert output probabilities to class indices
        target1 = torch.argmax(outputs1, dim=1)
        target2 = torch.argmax(outputs2, dim=1)
        
        # Compute cross-entropy loss
        loss = criterion(outputs1, target1) + criterion(outputs2, target2)
        
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
    print(f'Epoch {epoch+1}/{num_epochs}, Loss: {running_loss/len(train_loader)}')

and I get this error:

`E:\Anaconda\envs\torch\lib\site-packages\torch\nn\modules\rnn.py:878: UserWarning: RNN module weights are not part of single contiguous chunk of memory. This means they need to be compacted at every call, possibly greatly increasing memory usage. To compact weights again call flatten_parameters(). (Triggered internally at C:\cb\pytorch_1000000000000\work\aten\src\ATen\native\cudnn\RNN.cpp:982.)
  result = _VF.lstm(input, hx, self._flat_weights, self.bias, self.num_layers,
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Cell In[24], line 106
    104 data, labels = data.to(device), torch.tensor(labels).to(device)  # Move data to the GPU
    105 optimizer.zero_grad()
--> 106 outputs1, outputs2 = model(data[:, 0, :, None], data[:, 1, :, None])
    108 # Convert output probabilities to class indices
    109 target1 = torch.argmax(outputs1, dim=1)

File E:\Anaconda\envs\torch\lib\site-packages\torch\nn\modules\module.py:1511, in Module._wrapped_call_impl(self, *args, **kwargs)
   1509     return self._compiled_call_impl(*args, **kwargs)  # type: ignore[misc]
   1510 else:
-> 1511     return self._call_impl(*args, **kwargs)

File E:\Anaconda\envs\torch\lib\site-packages\torch\nn\modules\module.py:1520, in Module._call_impl(self, *args, **kwargs)
   1515 # If we don't have any hooks, we want to skip the rest of the logic in
   1516 # this function, and just call forward.
   1517 if not (self._backward_hooks or self._backward_pre_hooks or self._forward_hooks or self._forward_pre_hooks
   1518         or _global_backward_pre_hooks or _global_backward_hooks
   1519         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1520     return forward_call(*args, **kwargs)
   1522 try:
   1523     result = None

Cell In[24], line 12, in SiameseLSTM.forward(self, x1, x2)
     11 def forward(self, x1, x2):
---> 12     out1, _ = self.encoder(x1)
     13     out1 = out1[:, -1, :]  # Get the last output
     14     out2, _ = self.encoder(x2)  # Use the same LSTM instance for the second input

File E:\Anaconda\envs\torch\lib\site-packages\torch\nn\modules\module.py:1511, in Module._wrapped_call_impl(self, *args, **kwargs)
   1509     return self._compiled_call_impl(*args, **kwargs)  # type: ignore[misc]
   1510 else:
-> 1511     return self._call_impl(*args, **kwargs)

File E:\Anaconda\envs\torch\lib\site-packages\torch\nn\modules\module.py:1520, in Module._call_impl(self, *args, **kwargs)
   1515 # If we don't have any hooks, we want to skip the rest of the logic in
   1516 # this function, and just call forward.
   1517 if not (self._backward_hooks or self._backward_pre_hooks or self._forward_hooks or self._forward_pre_hooks
   1518         or _global_backward_pre_hooks or _global_backward_hooks
   1519         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1520     return forward_call(*args, **kwargs)
   1522 try:
   1523     result = None

File E:\Anaconda\envs\torch\lib\site-packages\torch\nn\modules\rnn.py:878, in LSTM.forward(self, input, hx)
    875         hx = self.permute_hidden(hx, sorted_indices)
    877 if batch_sizes is None:
--> 878     result = _VF.lstm(input, hx, self._flat_weights, self.bias, self.num_layers,
    879                       self.dropout, self.training, self.bidirectional, self.batch_first)
    880 else:
    881     result = _VF.lstm(input, batch_sizes, hx, self._flat_weights, self.bias,
    882                       self.num_layers, self.dropout, self.training, self.bidirectional)

RuntimeError: shape '[512, 1]' is invalid for input of size 34304

I dont understand why beacause it seems to work on CPU but has the problem when I change it to GPU.

tried to use "flatten_parameters()" but no use and also tried to pass both inputs (for siamese lstm branches)through same lstm instance

1

There are 1 best solutions below

0
user9998263 On

I had the same issue. In my case I had the wrong input_size to the model. It should be the number of features, I hade the sequence length instead which for some reason worked on the cpu but not gpu.