text: import time
  import torch
  import os
  
  
  def train(train_loader, model, criterion, optimizer, epoch, args):
      batch_time = AverageMeter()
      data_time = AverageMeter()
      losses = AverageMeter()
      top1 = AverageMeter()
      top5 = AverageMeter()
      model.train()
      adjust_learning_rate(optimizer, epoch, args)
      end = time.time()
      for i, (input, target) in enumerate(train_loader):
          # print(input)
          # print(target)
          data_time.update(time.time() - end)
          target = target.cuda(non_blocking=True)
          input_var = torch.autograd.Variable(input)
          target_var = torch.autograd.Variable(target)
          output = model(input_var)
          loss = criterion(output, target_var)
  
          #mesure accuracy and record loss
          prec1, prec5 = accuracy(output.data, target, topk=(1,5))
          losses.update(loss.data[0], input.size(0))
          top1.update(prec1[0], input.size(0))
          top5.update(prec5[0], input.size(0))
  
          #compute gradient and do SGD step
          optimizer.zero_grad()
          loss.backward()
          optimizer.step()
          batch_time.update(time.time() - end)
          end = time.time()
          if i % args.print_freq == 0:
              print('Train: [{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'
                    'Prec@1 {top1.val:.3f} ({top1.avg:.3f})\t'
                    'Prec@5 {top5.val:.3f} ({top5.avg:.3f})'.format(
                     epoch, i, len(train_loader), batch_time=batch_time,
                     data_time=data_time, loss=losses, top1=top1, top5=top5))
          args.num_train_iter -= 1
          if args.num_train_iter < 0:
              continue
          elif args.num_train_iter > 0:
              continue
          elif args.num_train_iter == 0:
              break
          
      log = open(os.path.join(args.log, 'log.txt'), 'a')
      log.write("\n")
      log.write("Train:epoch: %d, loss: %4f, Top1 acc: %3f, Top5 acc: %3f" % (epoch, losses.avg, top1.avg, top5.avg))
      log.close()
  
  
  def validate(val_loader, model, criterion, epoch, args):
      batch_time = AverageMeter()
      losses = AverageMeter()
      top1 = AverageMeter()
      top5 = AverageMeter()
      # switch to evaluate mode
      model.eval()
  
      end = time.time()
      for i, (input, target) in enumerate(val_loader):
          target = target.cuda(non_blocking=True)
          input_var = torch.autograd.Variable(input)#, volatile=True)
          target_var = torch.autograd.Variable(target)#, volatile=True)
  
          # compute output
          with torch.no_grad():
              output = model(input_var)
          loss = criterion(output, target_var)
  
          # measure accuracy and record loss
          prec1, prec5 = accuracy(output.data, target, topk=(1, 5))
          losses.update(loss.data[0], input.size(0))
          top1.update(prec1[0], input.size(0))
          top5.update(prec5[0], input.size(0))
  
          # measure elapsed time
          batch_time.update(time.time() - end)
          end = time.time()
  
          if i % args.print_freq == 0:
              print('Test: [{0}][{1}/{2}]\t'
                    'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
                    'Loss {loss.val:.4f} ({loss.avg:.4f})\t'
                    'Prec@1 {top1.val:.3f} ({top1.avg:.3f})\t'
                    'Prec@5 {top5.val:.3f} ({top5.avg:.3f})'.format(
                     epoch, i, len(val_loader), batch_time=batch_time, loss=losses,
                     top1=top1, top5=top5))
  
      print(' * Prec@1 {top1.avg:.3f} Prec@5 {top5.avg:.3f}'
            .format(top1=top1, top5=top5))
      log = open(os.path.join(args.log, 'log.txt'), 'a')
      log.write("\n")
      log.write("                               Test:epoch: %d, loss: %4f, Top1 acc: %3f, Top5 acc: %3f" %\
                (epoch, losses.avg, top1.avg, top5.avg))
      log.close()
      return top1.avg
  
  
  class AverageMeter(object):
      """Computes and stores the average and current value"""
      def __init__(self):
          self.reset()
  
      def reset(self):
          self.val = 0
          self.avg = 0
          self.sum = 0
          self.count = 0
  
      def update(self, val, n=1):
          self.val = val
          self.sum += val * n
          self.count += n
          self.avg = self.sum / self.count
  
  
  def adjust_learning_rate(optimizer, epoch, args):
      """Adjust the learning rate according the epoch"""
      exp = epoch > args.schedule[1] and 2 or epoch > args.schedule[0] and 1 or 0
      lr = args.lr * (args.gamma ** exp)
      for param_group in optimizer.param_groups:
          if args.new_fc:
              if param_group['name'] == 'pre-trained':
                  param_group['lr'] = 1e-3
              else:
                  param_group['lr'] = lr
          else:
              param_group['lr'] = lr
  
  
  def accuracy(output, target, topk=(1,)):
      """Computes the precision@k for the specified values of k"""
      maxk = max(topk)
      batch_size = target.size(0)
      _, pred = output.topk(maxk, 1, True, True)
      pred = pred.t()
      correct = pred.eq(target.view(1, -1).expand_as(pred))
  
      res = []
      for k in topk:
          correct_k = correct[:k].view(-1).float().sum(0, keepdim=True)
          res.append(correct_k.mul_(100.0 / batch_size))
      return res
  