def METHOD_NAME(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