Hey! I’m new to using PyTorch and I’m training my first RNN model, replicated from a paper.
I’m in the latter stages of the project, now I’m in the process of attempting to train the model.
But I keep getting this error:
IndexError: too many indices for tensor of dimension 0
I’m not entirely too sure why, though I suspect it has to do with the way I use torch.stack().
I’m inserting my code below if it helps!
class ChronoModel(LightningModule):
def __init__(self):
super(ChronoModel,self).__init__()
self.model=ChronoNet(14)
self.lr=1e-3 ##Defining learning rate of our model. .0001 per step size
self.bs=12 ## Defining the batch size
self.worker=2 ## Defining the # of workers, a parallel process
self.acc=torchmetrics.Accuracy(task='binary') ## For measuring accuracy of our model.
self.criterion = nn.BCEWithLogitsLoss() ## For measuring accuracy of our model based on the final Sigmoid Activation function.
self.train_outputs = [] #To store our outputs from training the model
self.val_outputs = [] # To store our outputs from validating the model
def forward(self,x): ## Defining forward function, for feeding our data into the model.
x=self.model(x)
return x
def configure_optimizers(self): ## Defining our optimizer
return torch.optim.Adam(self.parameters(), lr=self.lr) #Implementing the Adam optimizer on our model.
def train_dataloader(self): #Loads our training data
dataset = TensorDataset(train_features,train_labels) #Creates a tensor data object from our Tensors representing our training features
dataloader = DataLoader(dataset, batch_size=self.bs,num_workers = self.worker,shuffle=True) #Loads our data using the dataset, batch size, workers (parallel processes). Our data will be shuffled at each Epoch (per shuffle = True) to prevent overfitting.
return dataloader
def training_step(self,batch,batch_idx): #Defining our function for a single training step
signal,label = batch # From each batch, we unpack signal and label data
output=self(signal.float()) # Output of data given a signal
loss=self.criterion(output.flatten(),label.float().flatten()) #Calculating loss using the output and BCEWithLogitsLoss function
acc=self.acc(output.flatten(),label.long().flatten()) #Calculating the accuracy using the output and the Accuracy() function from torchmetrics
self.train_outputs.append(acc) # To append / add our output onto our training output list
return {'loss':loss,'acc':acc} # Returns our model loss and accuracy
def on_train_epoch_end(self):
acc=torch.stack([x['acc'] for x in self.train_outputs]).mean().detach().cpu().numpy().round(2) # Takes the average accuracy for the outputs and stacks it onto a singular Tensor. Then detaches it from the gpu, converts it into a NumPy array, round it to the nearest hundreth, and passes it onto the cpu
loss=torch.stack([x['loss'] for x in self.train_outputs]).mean().detach().cpu().numpy().round(2) # Takes the average loss for the outputs and stacks it onto a singular Tensor. Then detaches it from the gpu, converts it into a NumPy array, round it to the nearest hundreth, and passes it onto the cpu
self.train_outputs.clear() #To free up memory after each Epoch
print('train acc loss', acc,loss) # Printing our final training accuracy and loss
def val_dataloaders(self): #Loads our validation data
dataset = TensorDataset(val_features,val_labels) #Creates a tensor data object from our Tensors representing our validation features
dataloader = DataLoader(dataset, batch_size=self.bs,num_workers = self.worker,shuffle=True) #Loads our data using the dataset, batch size, workers (parallel processes). Our data will be shuffled at each Epoch (per shuffle = True) to prevent overfitting.
return dataloader
def validation_step(self,batch,batch_idx): #Defining our function for a single step
signal,label = batch # From each batch, we unpack signal and label data
output=self(signal.float()) # Output of data given a signal
loss=self.criterion(output.flatten(),label.float().flatten()) #Calculating loss using the output and BCEWithLogitsLoss function
acc=self.acc(output.flatten(),label.long().flatten()) #Calculating the accuracy using the output and the Accuracy() function from torchmetrics
self.val_outputs.append(acc) #To append / add our output onto our validation output list.
return {'loss':loss,'acc':acc} # Returns our model loss and accuracy
def on_validation_epoch_end(self):
acc=torch.stack([x['acc'] for x in self.val_outputs]).mean().detach().cpu().numpy().round(2) # Takes the average accuracy for the outputs and stacks it onto a singular Tensor. Then detaches it from the gpu, converts it into a NumPy array, round it to the nearest hundreth, and passes it onto the cpu
loss=torch.stack([x['loss'] for x in self.val_outputs]).mean().detach().cpu().numpy().round(2) # Takes the average loss for the outputs and stacks it onto a singular Tensor. Then detaches it from the gpu, converts it into a NumPy array, round it to the nearest hundreth, and passes it onto the cpu
self.val_outputs.clear() # To free up memory after each epoch.
print('val acc loss', acc, loss)