class_docstr: Model trainer
  
  Args:
      model(paddle.nn.Layer) : Model to train or evaluate.
      optimizer(paddle.optimizer.Optimizer) : Optimizer for loss.
      use_gpu(bool) : Whether to use gpu to run.
      use_vdl(bool) : Whether to use visualdl to record training data.
      checkpoint_dir(str) : Directory where the checkpoint is saved, and the trainer will restore the
          state and model parameters from the checkpoint.
      compare_metrics(callable) : The method of comparing the model metrics. If not specified, the main
          metric return by `validation_step` will be used for comparison by default, the larger the
          value, the better the effect. This method will affect the saving of the best model. If the
          default behavior does not meet your requirements, please pass in a custom method.
  
          Example:
              .. code-block:: python
  
                  def compare_metrics(old_metric: dict, new_metric: dict):
                      mainkey = list(new_metric.keys())[0]
                      return old_metric[mainkey] < new_metric[mainkey]
docstr: Run evaluation and returns metrics.
  
  Args:
      eval_dataset(paddle.io.Dataset) : The validation dataset
      batch_size(int) : Batch size of per step, default is 1.
      num_workers(int) : Number of subprocess to load data, default is 0.
      collate_fn(callable): function to generate mini-batch data by merging the sample list.
          None for only stack each fields of sample in axis 0(same as :attr::`np.stack(..., axis=0)`). Default None
docstr_tok: ["Run","evaluation","and","returns","metrics",".","Args",":","eval_dataset","(","paddle.io.Dataset",")",":","The","validation","dataset","batch_size","(","int",")",":","Batch","size","of","per","step",",","default","is","1.","num_workers","(","int",")",":","Number","of","subprocess","to","load","data",",","default","is","0.","collate_fn","(","callable",")",":","function","to","generate","mini-batch","data","by","merging","the","sample","list",".","None","for","only","stack","each","fields","of","sample","in","axis","0","(","same","as",":","attr",":",":","`","np.stack","(","...",",","axis=0",")","`",")",".","Default","None"]
code: def evaluate(
      self,
      eval_dataset: paddle.io.Dataset,
      batch_size: int = 1,
      num_workers: int = 0,
      collate_fn: Callable = None,
  ):
      """
      Run evaluation and returns metrics.
  
      Args:
          eval_dataset(paddle.io.Dataset) : The validation dataset
          batch_size(int) : Batch size of per step, default is 1.
          num_workers(int) : Number of subprocess to load data, default is 0.
          collate_fn(callable): function to generate mini-batch data by merging the sample list.
              None for only stack each fields of sample in axis 0(same as :attr::`np.stack(..., axis=0)`). Default None
      """
      if self.local_rank == 0:
          batch_sampler = paddle.io.BatchSampler(
              eval_dataset,
              batch_size=batch_size,
              shuffle=False,
              drop_last=False,
          )
  
          loader = paddle.io.DataLoader(
              eval_dataset,
              batch_sampler=batch_sampler,
              num_workers=num_workers,
              return_list=True,
              collate_fn=collate_fn,
          )
  
          self.model.eval()
  
          avg_loss = num_samples = 0
          sum_metrics = defaultdict(int)
          avg_metrics = defaultdict(int)
  
          with logger.processing("Evaluation on validation dataset"):
              with paddle.no_grad():
                  for batch_idx, batch in enumerate(loader):
                      result = self.validation_step(batch, batch_idx)
  
                      loss = result.get("loss", None)
                      metrics = result.get("metrics", {})
                      bs = batch[0].shape[0]
                      num_samples += bs
  
                      if loss:
                          avg_loss += float(loss) * bs
  
                      for metric, value in metrics.items():
                          sum_metrics[metric] += value * bs
  
          # print avg metrics and loss
          print_msg = "[Evaluation result]"
          if loss:
              avg_loss /= num_samples
              print_msg += " avg_loss={:.4f}".format(avg_loss)
  
          for metric, value in sum_metrics.items():
              avg_metrics[metric] = float(value) / num_samples
              print_msg += " avg_{}={:.4f}".format(
                  metric, avg_metrics[metric]
              )
  
          logger.eval(print_msg)
  
          if loss:
              return {"loss": avg_loss, "metrics": avg_metrics}
          return {"metrics": avg_metrics}
  
imports: import os
  import pickle
  import time
  from collections import defaultdict
  from typing import Any
  from typing import Callable
  from typing import Generic
  from typing import List
  import numpy
  import paddle
  from visualdl import LogWriter
  from paddlehub.utils.log import logger
  from paddlehub.utils.utils import Timer
label_desc: Use image node_id 9 for calling the Trainer obj's underlying member method code with example usage: obj.evaluate(eval_dataset, batch_size, num_workers, collate_fn) and returns: dict, dict