Well, thanks I have done that, but the result ends up in a very confusing manner, See it is my code -
for epoch in range(epochs):
  
  running_loss = 0
  model.train()
  for images, labels in dataloader_train:
    
    #steps += 1
    images, labels = images.to(device), labels.to(device)
    
    optimizer.zero_grad()
    
    output = model.forward(images)
    conf_matrix = confusion_matrix(output, labels, conf_matrix)
    p = torch.nn.functional.softmax(output, dim=1)
    prediction = torch.argmax(p, dim=1)
    #loss = torch.nn.functional.nll_loss(torch.log(p), y)
    loss = criterion(output, labels)
    loss.backward()
    optimizer.step()
    
    running_loss += loss.item()
    
  #if steps % print_every == 0:
  valid_loss = 0
  accuracy = 0
  model.eval()
  for images, labels in dataloader_test:
    optimizer.zero_grad()
    with torch.no_grad():
       
      images, labels = images.to(device), labels.to(device)

      output = model.forward(images)
      conf_matrix = confusion_matrix(output, labels, conf_matrix)
      p = torch.nn.functional.softmax(output, dim=1)
      prediction = torch.argmax(p, dim=1)
      loss = criterion(output, labels)
          
      valid_loss += loss.item()
          
      ps = torch.exp(output)
         
      top_p, top_class = ps.topk(1, dim = 1)
      equals = top_class == labels.view(*top_class.shape)
      accuracy += torch.mean(equals.type(torch.FloatTensor))
        
  print("Epoch: {}/{} " .format(epoch+1, epochs))
  print("Train loss: {:.4f}.. " .format(running_loss/len(dataloader_train)))
  print("Valid loss: {:.4f}.. " .format(valid_loss/len(dataloader_test)))
  print("Accuracy: {:.4f}.. " .format(accuracy/len(dataloader_test)))
  model.train()

So, the result in this case comes in almost 100 times repeting this(obviously with different values) per epoch  -
tensor([[6639., 1154., 1566.,  632.],
        [ 744., 3288.,  726.,  758.],
        [1111.,  772., 3596.,  850.],
        [ 519., 1084., 1266., 4964.]])
Class 0
TP 6639.0, TN 17304.0, FP 3352.0, FN 2374.0
Sensitivity = 0.7366026639938354
Specificity = 0.8377227187156677
Class 1
TP 3288.0, TN 21143.0, FP 2228.0, FN 3010.0
Sensitivity = 0.5220705270767212
Specificity = 0.9046681523323059
Class 2
TP 3596.0, TN 19782.0, FP 2733.0, FN 3558.0
Sensitivity = 0.5026558637619019
Specificity = 0.8786142468452454
Class 3
TP 4964.0, TN 19596.0, FP 2869.0, FN 2240.0
Sensitivity = 0.6890616416931152
Specificity = 0.8722902536392212

But I want this result to be repeted only once, for each train and validation/test loop. So I have done this -
for images, labels in dataloader_train:
    
    #steps += 1
    images, labels = images.to(device), labels.to(device)
    
    optimizer.zero_grad()
    
    output = model.forward(images)
    conf_matrix = confusion_matrix(output, labels, conf_matrix)
    p = torch.nn.functional.softmax(output, dim=1)
    prediction = torch.argmax(p, dim=1)
    #loss = torch.nn.functional.nll_loss(torch.log(p), y)
    loss = criterion(output, labels)
    loss.backward()
    optimizer.step()
    
    running_loss += loss.item()
    
  #if steps % print_every == 0:
  valid_loss = 0
  accuracy = 0
  conf_matrix = confusion_matrix(output, labels, conf_matrix)
  model.eval()

But, this is out of the loop, so will not work, can you guide me why this happening? Is it for the 1000 images? But why? Because there is the only dataloader_train, should return only the values of training dataset, right? I am not getting this.