I make model training (which goes fine, with no error, loss is decreasing and accuracy is increasing), however if I add validation part, the cell gives me an error.
index out of range in self
If I try to repeat the error by going through the model code separately with X_val and y_val data – everything works. If I try to run the model as function, I get the same error.
The shape of batches and arrays are the same as for X_train and y_train.
train_batches = round(len(X_train)/batch_size)

for epoch in range(10):

    model.train()
    train_loss_sum=0
    train_acc_sum=0
    for train_bat in range (train_batches):
        batch_ix = np.random.randint(len(X_train), size=batch_size)
        batch_inp = X_train.iloc[batch_ix]
        batch_out = torch.tensor(y_train.iloc[batch_ix].values).to(torch.float32)
        cat_tensor = torch.tensor(batch_inp[cat_cols].values).to(torch.int64)
        num_tensor = torch.tensor(batch_inp[num_cols].values).to(torch.int64)
        model_pred = model(num_tensor, cat_tensor)

        opt.zero_grad()
        train_loss = loss_fn(model_pred, batch_out)    
        train_loss.backward()
        opt.step()
        
        train_loss_sum+=train_loss.item()
        train_acc_sum += ((model_pred > 0.0) == batch_out).sum()/len(batch_out)
    
    model.eval()
    val_loss_sum=0
    val_acc_sum=0
    with torch.no_grad():
        for val_bat in range (val_batches):
             print(ep, val_bat, i)
             val_batch_ix = np.random.randint(len(X_val), size=batch_size)
             val_batch_inp = X_val.iloc[val_batch_ix]
             val_batch_out = torch.tensor(y_val.iloc[val_batch_ix].values).to(torch.float32)
             val_cat_tensor = torch.tensor(val_batch_inp[cat_cols].values).to(torch.int64)
             val_num_tensor = torch.tensor(val_batch_inp[num_cols].values).to(torch.int64)
             val_out = model(val_cat_tensor, val_num_tensor)
            
             val_loss = loss_fn(val_out, val_batch_out)
             val_loss_sum += val_loss.item()
             val_acc_sum += ((val_out > 0.0) == batch_out).sum()/len(val_batch_out)
             val_acc_sum+=((torch.max(val_out,dim=1)[1]==val_label).sum().item())/len(val_label)


    val_avg_loss=np.round(val_loss_sum/len(val_batches),2)#val loss of all batches of one epoch
    train_avg_loss=np.round(train_loss_sum/train_batches,2)# train loss of all batches of one epoch
    train_avg_acc=np.round(train_acc_sum/train_batches,2)#train acc of all batches of one epoch
    val_avg_acc=np.round(val_acc_sum/len(val_batches),2)#val acc of all batches of one epoch

    print('Epoch {}, train acc  {}, train loss {} , val acc is {}, loss is {}, learning rate is {} '.format(epoch, train_avg_acc, train_avg_loss, val_avg_acc, val_avg_loss, opt.param_groups[0]['lr']))

The model itself it:
                 embedding_dim_dict=None, learning_rate=0.01):
        super().__init__()

        self.cat_cols = cat_cols
        self.num_cols = num_cols
        self.embeddings, total_embedding_dim = self._create_embedding_layers(
            cat_cols, embedding_size_dict, embedding_dim_dict)
        
        in_features = len(num_cols) + total_embedding_dim
        self.layers = nn.Sequential(
            nn.Linear(in_features, 128),
            nn.ReLU(),
            nn.Linear(128, 256),
            nn.ReLU(),
            nn.Linear(256, n_classes)
        )

    @staticmethod
    def _create_embedding_layers(cat_cols, embedding_size_dict, embedding_dim_dict):
        """construct the embedding layer, 1 per each categorical variable"""
        total_embedding_dim = 0
        embeddings = {}
        for col in cat_cols:
            embedding_size = embedding_size_dict[col]
            embedding_dim = embedding_dim_dict[col]
            total_embedding_dim += embedding_dim
            embeddings[col] = nn.Embedding(embedding_size, embedding_dim)

        return nn.ModuleDict(embeddings), total_embedding_dim

    def forward(self, num_tensor, cat_tensor):
        cat_outputs = []
        for i, col in enumerate(self.cat_cols):
            embedding = self.embeddings[col]
            cat_output = embedding(cat_tensor[:, i])
            cat_outputs.append(cat_output)
        
        cat_outputs = torch.cat(cat_outputs, dim=1)
        all_outputs = torch.cat((num_tensor, cat_outputs), dim=1)
        
        final_outputs = self.layers(all_outputs).squeeze(dim=1)
        return final_outputs

And the error happens here when val_out is calculated:
     46             embedding = self.embeddings[col]
---> 47             cat_output = embedding(cat_tensor[:, i])
     48             cat_outputs.append(cat_output)

I rechecked the shape of tensors and removed any other iterations using “i” just in case.