def eval_epoch()

in tools/epic/handobj/train_net.py [0:0]


def eval_epoch(val_loader, model, val_meter, cur_epoch, cfg, writer=None):
    """
    Evaluate the model on the val set.
    Args:
        val_loader (loader): data loader to provide validation data.
        model (model): model to evaluate the performance.
        val_meter (ValMeter): meter instance to record and calculate the metrics.
        cur_epoch (int): number of the current epoch of training.
        cfg (CfgNode): configs. Details can be found in
            slowfast/config/defaults.py
        writer (TensorboardWriter, optional): TensorboardWriter object
            to writer Tensorboard log.
    """

    # Evaluation mode enabled. The running stats would not be updated.
    model.eval()
    val_meter.iter_tic()

    for cur_iter, (inputs, labels, _, meta) in enumerate(val_loader):
        # Transferthe data to the current GPU device.
        if isinstance(inputs, (list,)):
            for i in range(len(inputs)):
                inputs[i] = inputs[i].cuda(non_blocking=True)
        else:
            inputs = inputs.cuda(non_blocking=True)
        labels = labels.cuda()
        for key, val in meta.items():
            if isinstance(val, (list,)):
                for i in range(len(val)):
                    val[i] = val[i].cuda(non_blocking=True)
            else:
                meta[key] = val.cuda(non_blocking=True)

        preds, _ = model(inputs, meta)

        verb_preds, noun_preds = preds[:2]
        verb_labels, noun_labels = labels[:, 0], labels[:, 1]
        # Compute the errors.
        ks = (1, 5)
        verb_num_topks_correct = metrics.topks_correct(verb_preds, verb_labels, ks)
        noun_num_topks_correct = metrics.topks_correct(noun_preds, noun_labels, ks)
        action_num_topks_correct = metrics.multitask_topks_correct(
            (verb_preds, noun_preds),
            (verb_labels, noun_labels),
            ks,
        )
        verb_top1_err, verb_top5_err  = [
            (1.0 - x / verb_preds.size(0)) * 100.0 for x in verb_num_topks_correct
        ]
        noun_top1_err, noun_top5_err  = [
            (1.0 - x / noun_preds.size(0)) * 100.0 for x in noun_num_topks_correct
        ]
        top1_err, top5_err  = [
            (1.0 - x / verb_preds.size(0)) * 100.0 for x in action_num_topks_correct
        ]
        if cfg.NUM_GPUS > 1:
            top1_err, top5_err, verb_top1_err, verb_top5_err, noun_top1_err, noun_top5_err = du.all_reduce(
                [top1_err, top5_err, verb_top1_err, verb_top5_err, noun_top1_err, noun_top5_err]
            )

        # Copy the errors from GPU to CPU (sync point).
        top1_err, top5_err, verb_top1_err, verb_top5_err, noun_top1_err, noun_top5_err= (
            top1_err.item(), 
            top5_err.item(), 
            verb_top1_err.item(),
            verb_top5_err.item(),
            noun_top1_err.item(), 
            noun_top5_err.item(),
        )

        stats = {
            "verb_top1_err": verb_top1_err,
            "verb_top5_err": verb_top5_err,
            "noun_top1_err": noun_top1_err,
            "noun_top5_err": noun_top5_err,
        }

        val_meter.iter_toc()
        # Update and log stats.
        val_meter.update_stats(
            top1_err, top5_err, inputs[0].size(0) * cfg.NUM_GPUS, stats=stats
        )
        # write to tensorboard format if available.
        if writer is not None:
            writer.add_scalars(
                {"Val/Top1_err": top1_err, "Val/Top5_err": top5_err},
                global_step=len(val_loader) * cur_epoch + cur_iter,
            )

        val_meter.update_predictions(preds, labels)

        val_meter.log_iter_stats(cur_epoch, cur_iter)
        val_meter.iter_tic()

    # Log epoch stats.
    is_best_epoch = val_meter.log_epoch_stats(cur_epoch)
    # write to tensorboard format if available.

    val_meter.reset()

    return is_best_epoch