Plotting training and accuracy and loss after training completion?

I want to plot my training loss and accuracy after I finished the training
this is the function of the training

import torch
import time
import os
import sys

import torch
import torch.distributed as dist

from utils import AverageMeter, calculate_accuracy

import matplotlib.pyplot as plt

def train_epoch(epoch,
                data_loader,
                model,
                criterion,
                optimizer,
                device,
                current_lr,
                epoch_logger,
                batch_logger,
                tb_writer=None,
                distributed=False):
    print('train at epoch {}'.format(epoch))

    model.train()    
    batch_time = AverageMeter()
    data_time = AverageMeter()
    losses = AverageMeter()
    accuracies = AverageMeter()

    end_time = time.time()
    for i, (inputs, targets) in enumerate(data_loader):
        data_time.update(time.time() - end_time)

        targets = targets.to(device, non_blocking=True)
        outputs = model(inputs)
        loss = criterion(outputs, targets)
        acc = calculate_accuracy(outputs, targets)

        losses.update(loss.item(), inputs.size(0))
        accuracies.update(acc, inputs.size(0))

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        batch_time.update(time.time() - end_time)
        end_time = time.time()

        if batch_logger is not None:
            batch_logger.log({
                'epoch': epoch,
                'batch': i + 1,
                'iter': (epoch - 1) * len(data_loader) + (i + 1),
                'loss': losses.val,
                'acc': accuracies.val,
                'lr': current_lr
            })

        print('Epoch: [{0}][{1}/{2}]\t'
              'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
              'Data {data_time.val:.3f} ({data_time.avg:.3f})\t'
              'Loss {loss.val:.4f} ({loss.avg:.4f})\t'
              'Acc {acc.val:.3f} ({acc.avg:.3f})'.format(epoch,
                                                         i + 1,
                                                         len(data_loader),
                                                         batch_time=batch_time,
                                                         data_time=data_time,
                                                         loss=losses,
                                                         acc=accuracies))

    if distributed:
        loss_sum = torch.tensor([losses.sum],
                                dtype=torch.float32,
                                device=device)
        loss_count = torch.tensor([losses.count],
                                  dtype=torch.float32,
                                  device=device)
        acc_sum = torch.tensor([accuracies.sum],
                               dtype=torch.float32,
                               device=device)
        acc_count = torch.tensor([accuracies.count],
                                 dtype=torch.float32,
                                 device=device)

        dist.all_reduce(loss_sum, op=dist.ReduceOp.SUM)
        dist.all_reduce(loss_count, op=dist.ReduceOp.SUM)
        dist.all_reduce(acc_sum, op=dist.ReduceOp.SUM)
        dist.all_reduce(acc_count, op=dist.ReduceOp.SUM)

        losses.avg = loss_sum.item() / loss_count.item()
        accuracies.avg = acc_sum.item() / acc_count.item()

    if epoch_logger is not None:
        epoch_logger.log({
            'epoch': epoch,
            'loss': losses.avg,
            'acc': accuracies.avg,
            'lr': current_lr
        })

    if tb_writer is not None:
        tb_writer.add_scalar('train/loss', losses.avg, epoch)
        tb_writer.add_scalar('train/acc', accuracies.avg, epoch)
        tb_writer.add_scalar('train/lr', accuracies.avg, epoch)
       

this will be used by the main function as


    if opt.is_master_node:
        train_logger = Logger(opt.result_path / 'train.log',
                              ['epoch', 'loss', 'acc', 'lr'])
        train_batch_logger = Logger(
            opt.result_path / 'train_batch.log',
            ['epoch', 'batch', 'iter', 'loss', 'acc', 'lr'])
    else:
        train_logger = None
        train_batch_logger = None

    if opt.nesterov:
        dampening = 0
    else:
        dampening = opt.dampening
    optimizer = SGD(model_parameters,
                    lr=opt.learning_rate,
                    momentum=opt.momentum,
                    dampening=dampening,
                    weight_decay=opt.weight_decay,
                    nesterov=opt.nesterov)

    assert opt.lr_scheduler in ['plateau', 'multistep']
    assert not (opt.lr_scheduler == 'plateau' and opt.no_val)
    if opt.lr_scheduler == 'plateau':
        scheduler = lr_scheduler.ReduceLROnPlateau(
            optimizer, 'min', patience=opt.plateau_patience)
    else:
        scheduler = lr_scheduler.MultiStepLR(optimizer,
                                             opt.multistep_milestones)

    return (train_loader, train_sampler, train_logger, train_batch_logger,
            optimizer, scheduler)

know how can I plot the results tha t I got 
I tried creating two lists
and then used a loop to plot the values
train_losses=[]
train_accuracies=[]
train_losses.append(losses.avg)
train_accuracies.append(accuracies.avg)

Plot training and validation losses

for n in range (50) :
   plt.figure(figsize=(10, 5))
   plt.plot(range(epoch),train_losses, label='Train Loss')
   plt.plot(range(epoch),train_accuracies, label='Train Accuracy')
   plt.title('Training and Validation Losses')
   plt.xlabel('Epoch')
   plt.ylabel('Loss')
   plt.legend()
   plt.show()

inside the training function but I didn’t get any result
did I misplaced the function ,I am a bit confused can someone help meb ?

Hi Amy!

Here you create an empty list and append a single element to it. Even if
you run this in a loop, each time in the loop you will create a new empty
list, so at the end train_losses (and also train_accuracies) will be a
list containing a single element.

If you plot a list with just a single element, you might not see much of
anything in the plot.

I’m not sure what you’re trying to do with the for n in range (50) loop.
(This won’t plot fifty separate points on a single plot, if that’s your goal.)

This code, as posted, plots the same plot over and over again, fifty times
(displayed sequentially by the plt.show() in the loop).

Note that the x and y arguments to plot (x, y) have to have the same
length, otherwise plot (x, y) will raise an error. So, if epoch is not 1,
you’ll get an error, while if epoch is 1, you’ll be plotting just a single point.

You might want to try something like:

train_losses=[]   # before training loop

for  i in range (num_epochs):   # run full training loop
    # train for one epoch ...
    loss = compute_loss_for_epoch()
    train_losses.append (loss)

# outside of loop
plt.plot (range (num_epochs), train_losses, label = 'Train Loss')
plt.show()

Here, the x argument to plot() has length num_epochs, as does the y
argument, the list of loss values, train_losses. So this will display a single
plot with num_epochs points.

Best.

K. Frank