code: def train(self, validation_frequency=1):
      best_acc = 0
      nBatch = len(self.train_loader)
  
      def train_log_func(
          epoch_, i, batch_time, data_time, losses, top1, top5, lr
      ):
          batch_log = (
              "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 {losses.val:.4f} ({losses.avg:.4f})\t"
              "Top-1 acc {top1.val:.3f} ({top1.avg:.3f})".format(
                  epoch_ + 1,
                  i,
                  nBatch - 1,
                  batch_time=batch_time,
                  data_time=data_time,
                  losses=losses,
                  top1=top1,
              )
          )
          batch_log += (
              "\tTop-5 acc {top5.val:.3f} ({top5.avg:.3f})".format(
                  top5=top5
              )
          )
          batch_log += "\tlr {lr:.5f}".format(lr=lr)
          return batch_log
  
      def adjust_learning_rate(
          n_epochs, optimizer, epoch, batch=0, nBatch=None
      ):
          """adjust learning of a given optimizer and return the new learning rate"""
          # cosine
          T_total = n_epochs * nBatch
          T_cur = epoch * nBatch + batch
          # init_lr = 0.05
          new_lr = (
              0.5 * 0.05 * (1 + math.cos(math.pi * T_cur / T_total))
          )
          for param_group in optimizer.param_groups:
              param_group["lr"] = new_lr
          return new_lr
  
      for epoch in range(self.n_epochs):
          print(
              "\n",
              "-" * 30,
              "Train epoch: %d" % (epoch + 1),
              "-" * 30,
              "\n",
          )
          end = time.time()
          train_top1, train_top5 = self.train_one_epoch(
              lambda i: adjust_learning_rate(
                  self.n_epochs, self.optimizer, epoch, i, nBatch
              ),
              lambda i, batch_time, data_time, losses, top1, top5, new_lr: train_log_func(
                  epoch,
                  i,
                  batch_time,
                  data_time,
                  losses,
                  top1,
                  top5,
                  new_lr,
              ),
          )
          time_per_epoch = time.time() - end
          seconds_left = int(
              (self.n_epochs - epoch - 1) * time_per_epoch
          )
          print(
              "Time per epoch: %s, Est. complete in: %s"
              % (
                  str(timedelta(seconds=time_per_epoch)),
                  str(timedelta(seconds=seconds_left)),
              )
          )
  
          if (epoch + 1) % validation_frequency == 0:
              val_loss, val_acc, val_acc5 = self.validate(is_test=False)
              is_best = val_acc > best_acc
              best_acc = max(best_acc, val_acc)
              val_log = "Valid [{0}/{1}]\tloss {2:.3f}\ttop-1 acc {3:.3f} ({4:.3f})".format(
                  epoch + 1, self.n_epochs, val_loss, val_acc, best_acc
              )
              val_log += "\ttop-5 acc {0:.3f}\tTrain top-1 {top1.avg:.3f}\ttop-5 {top5.avg:.3f}".format(
                  val_acc5, top1=train_top1, top5=train_top5
              )
              print(val_log)
          else:
              is_best = False
  
file_path: nni/examples/nas/legacy/oneshot/proxylessnas/retrain.py
imports: import time
  import math
  from datetime import timedelta
  import torch
  from torch import nn
  from nni.nas.pytorch.utils import AverageMeter
label_desc: Use image node_id 4 for calling the Retrain obj's underlying member method code with example usage: obj.train(validation_frequency) and returns: batch_log, new_lr