I am trying to plot the train loss and validation loss in the same window in Visdom but it’s giving me one line instead of two and also wrong values.
this is the snippet I am using.
criterion = nn.NLLLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)  # 1e-3
#optimizer = optim.SGD(model.parameters(), lr=0.00001, momentum=0.9)  # 1e-3

# Decay LR by a factor of 0.1 every 4 epochs.
#step size: Period of learning rate decay.
#gamma = Multiplicative factor of learning rate decay. Default: 0.1, should float
scheduler = lr_scheduler.StepLR(optimizer, step_size=2, gamma=0.1)


def train_model(model, criterion, optimizer, scheduler, num_epochs=4):
    
    vis = visdom.Visdom()
    loss_window = vis.line(X=numpy.zeros((1 ,)),
                           Y=numpy.zeros((1)),
                           opts=dict(xlabel='epoch',
                                     ylabel='Loss',
                                     title='epoch Loss and accuracy',
                                     ))                    
    since = time.time()
        
    best_model_wts = copy.deepcopy(model.state_dict())
    best_acc = 0.0
    
    for epoch in range(num_epochs):  # loop over the dataset multiple times
        print('Epoch {}/{}'.format(epoch, num_epochs - 1))
        print('-' * 30)
        
        # Each epoch has a training and validation phase
        for phase in ['train', 'valid']:
            if phase == 'train':
                scheduler.step()
                
                model.train()  # Set model to training mode
            else:
                model.eval()   # Set model to evaluate mode
        
            train_loss = 0.0
            total_train = 0
            correct_train = 0
        
            #iterate over data
            for t_image, mask, image_paths, target_paths in dataLoaders[phase]:
                
                # get the inputs
                t_image = t_image.to(device)
                mask = mask.to(device)
                                
                 # zeroes the gradient buffers of all parameters
                optimizer.zero_grad()
                
                # forward
                # track history if only in train
                with torch.set_grad_enabled(phase == 'train'):
                    outputs = model(t_image) 
                    _, predicted = torch.max(outputs.data, 1)
                    loss = criterion(outputs, mask) # calculate the loss
            
                    # backward + optimize only if in training phase
                    if phase == 'train':
                        loss.backward() # back propagation
                        optimizer.step() # update gradients                        
            
                # accuracy
                train_loss += loss.item()
                total_train += mask.nelement()  # number of pixel in the batch
                correct_train += predicted.eq(mask.data).sum().item() # sum all precited pixel values            
                        
            epoch_loss = train_loss / len(dataLoaders[phase].dataset)
            epoch_acc = (correct_train / total_train)

            print('{} Loss: {:.4f} Acc: {:.4f}'.format(
                phase, epoch_loss, epoch_acc))

            X1 = numpy.ones((1, 1))*epoch
            Y1 = numpy.array([epoch_loss ])
            Y2 = numpy.array([epoch_loss ])
            vis.line(
                    X=numpy.column_stack((X1, X1)),
                    Y=numpy.column_stack((Y1, Y2)),
                    win=loss_window,
                    update='append')

             #deep copy the model
            if phase == 'val' and epoch_acc > best_acc:
                best_acc = epoch_acc
                best_model_wts = copy.deepcopy(model.state_dict())
            
        print()
    time_elapsed = time.time() - since
    print('Training complete in {:.0f}m {:.0f}s'.format(
        time_elapsed // 60, time_elapsed % 60))
    print('Best val Acc: {:4f}'.format(best_acc))

    torch.save(model.state_dict(), 'train_valid_exp1.pth')   
    # load best model weights
    model.load_state_dict(best_model_wts)
    return model
           
if __name__=='__main__':
    train_model()