code: def evaluate(
      model_G, criterion_G, model_D, criterion_D, ap, global_step, epoch
  ):
      data_loader = setup_loader(ap, is_val=True, verbose=(epoch == 0))
      model_G.eval()
      model_D.eval()
      epoch_time = 0
      keep_avg = KeepAverage()
      end_time = time.time()
      c_logger.print_eval_start()
      for num_iter, data in enumerate(data_loader):
          start_time = time.time()
  
          # format data
          c_G, y_G, _, _ = format_data(data)
          loader_time = time.time() - end_time
  
          global_step += 1
  
          ##############################
          # GENERATOR
          ##############################
  
          # generator pass
          y_hat = model_G(c_G)
          y_hat_sub = None
          y_G_sub = None
  
          # PQMF formatting
          if y_hat.shape[1] > 1:
              y_hat_sub = y_hat
              y_hat = model_G.pqmf_synthesis(y_hat)
              y_G_sub = model_G.pqmf_analysis(y_G)
  
          scores_fake, feats_fake, feats_real = None, None, None
          if global_step > c.steps_to_start_discriminator:
              if len(signature(model_D.forward).parameters) == 2:
                  D_out_fake = model_D(y_hat, c_G)
              else:
                  D_out_fake = model_D(y_hat)
              D_out_real = None
  
              if c.use_feat_match_loss:
                  with torch.no_grad():
                      D_out_real = model_D(y_G)
  
              # format D outputs
              if isinstance(D_out_fake, tuple):
                  scores_fake, feats_fake = D_out_fake
                  if D_out_real is None:
                      feats_real = None
                  else:
                      _, feats_real = D_out_real
              else:
                  scores_fake = D_out_fake
                  feats_fake, feats_real = None, None
  
          # compute losses
          loss_G_dict = criterion_G(
              y_hat,
              y_G,
              scores_fake,
              feats_fake,
              feats_real,
              y_hat_sub,
              y_G_sub,
          )
  
          loss_dict = dict()
          for key, value in loss_G_dict.items():
              if isinstance(value, (int, float)):
                  loss_dict[key] = value
              else:
                  loss_dict[key] = value.item()
  
          ##############################
          # DISCRIMINATOR
          ##############################
  
          if global_step >= c.steps_to_start_discriminator:
              # discriminator pass
              with torch.no_grad():
                  y_hat = model_G(c_G)
  
              # PQMF formatting
              if y_hat.shape[1] > 1:
                  y_hat = model_G.pqmf_synthesis(y_hat)
  
              # run D with or without cond. features
              if len(signature(model_D.forward).parameters) == 2:
                  D_out_fake = model_D(y_hat.detach(), c_G)
                  D_out_real = model_D(y_G, c_G)
              else:
                  D_out_fake = model_D(y_hat.detach())
                  D_out_real = model_D(y_G)
  
              # format D outputs
              if isinstance(D_out_fake, tuple):
                  scores_fake, feats_fake = D_out_fake
                  if D_out_real is None:
                      scores_real, feats_real = None, None
                  else:
                      scores_real, feats_real = D_out_real
              else:
                  scores_fake = D_out_fake
                  scores_real = D_out_real
  
              # compute losses
              loss_D_dict = criterion_D(scores_fake, scores_real)
  
              for key, value in loss_D_dict.items():
                  if isinstance(value, (int, float)):
                      loss_dict[key] = value
                  else:
                      loss_dict[key] = value.item()
  
          step_time = time.time() - start_time
          epoch_time += step_time
  
          # update avg stats
          update_eval_values = dict()
          for key, value in loss_dict.items():
              update_eval_values["avg_" + key] = value
          update_eval_values["avg_loader_time"] = loader_time
          update_eval_values["avg_step_time"] = step_time
          keep_avg.update_values(update_eval_values)
  
          # print eval stats
          if c.print_eval:
              c_logger.print_eval_step(
                  num_iter, loss_dict, keep_avg.avg_values
              )
  
      if args.rank == 0:
          # compute spectrograms
          figures = plot_results(y_hat, y_G, ap, global_step, "eval")
          tb_logger.tb_eval_figures(global_step, figures)
  
          # Sample audio
          sample_voice = y_hat[0].squeeze(0).detach().cpu().numpy()
          tb_logger.tb_eval_audios(
              global_step,
              {"eval/audio": sample_voice},
              c.audio["sample_rate"],
          )
  
          tb_logger.tb_eval_stats(global_step, keep_avg.avg_values)
  
      # synthesize a full voice
      data_loader.return_segments = False
  
      return keep_avg.avg_values
  
imports: import argparse
  import glob
  import os
  import sys
  import time
  import traceback
  from inspect import signature
  import torch
  from torch.utils.data import DataLoader
  from TTS.utils.audio import AudioProcessor
  from TTS.utils.console_logger import ConsoleLogger
  from TTS.utils.generic_utils import KeepAverage, count_parameters, create_experiment_folder, get_git_branch, remove_experiment_folder, set_init_dict
  from TTS.utils.io import copy_model_files, load_config
  from TTS.utils.radam import RAdam
  from TTS.utils.tensorboard_logger import TensorboardLogger
  from TTS.utils.training import setup_torch_training_env
  from TTS.vocoder.datasets.gan_dataset import GANDataset
  from TTS.vocoder.datasets.preprocess import load_wav_data, load_wav_feat_data
  from TTS.vocoder.layers.losses import DiscriminatorLoss, GeneratorLoss
  from TTS.vocoder.utils.generic_utils import plot_results, setup_discriminator, setup_generator
  from TTS.vocoder.utils.io import save_best_model, save_checkpoint
  from torch.nn.parallel import DistributedDataParallel
  from torch.utils.data.distributed import DistributedSampler
  from TTS.utils.distribute import init_distributed
label_desc: Use image node_id 4 for calling a global function with example usage: evaluate(model_G, criterion_G, model_D, criterion_D, ap, global_step, epoch) and returns: keep_avg