class_docstr: A trainer for `AbstractComponent`s. Used mainly for supervised learning.
  
  Create a `ModelTrainer` by passing a `AbstractNeuralModel` in the constructor.
  Invoke `train()` to initiate the training loop. The root `TNeuralModule` should return a scalar loss.
class_docstr_tok: ["A","trainer","for","`","AbstractComponent","`","s",".","Used","mainly","for","supervised","learning",".","Create","a","`","ModelTrainer","`","by","passing","a","`","AbstractNeuralModel","`","in","the","constructor",".","Invoke","`","train","(",")","`","to","initiate","the","training","loop",".","The","root","`","TNeuralModule","`","should","return","a","scalar","loss","."]
code: def _run_validation(
      self,
      validation_tensors,
      epoch,
      best_target_metric,
      device,
      parallelize,
      show_progress_bar,
  ):
      self.neural_module.eval()
      sum_epoch_loss, num_minibatches, num_samples = 0.0, 0, 0
      start_time = time.time()
      with tqdm(
          desc="Validation", disable=not show_progress_bar, leave=False
      ) as progress_bar, torch.no_grad():
          for mb_data, raw_samples in self.__model.minibatch_iterator(
              validation_tensors(),
              device=device,
              max_minibatch_size=self._minibatch_size,
              yield_partial_minibatches=True,
              shuffle_input=False,
              parallelize=parallelize,
          ):
              with catch_cuda_oom(self._catch_cuda_ooms):
                  with torch.cuda.amp.autocast(
                      enabled=self._enable_amp
                  ):
                      mb_loss = self.neural_module(**mb_data)
                  num_minibatches += 1
                  num_samples += len(raw_samples)
                  sum_epoch_loss += mb_loss
                  if show_progress_bar:
                      progress_bar.update()
                      progress_bar.set_postfix(
                          Loss=f"{float(sum_epoch_loss) / num_minibatches:.2f}"
                      )
  
      elapsed_time = time.time() - start_time
      assert num_samples > 0, "No validation data was found."
  
      validation_loss = sum_epoch_loss / num_minibatches
      self.LOGGER.info(
          "Validation complete in %.1fsec [%.2f samples/sec]",
          elapsed_time,
          (num_samples / elapsed_time),
      )
      self.LOGGER.info(
          "Epoch %i: Valid Loss %.2f", epoch + 1, validation_loss
      )
  
      validation_metrics = self.neural_module.report_metrics()
      for epoch_hook in self._validation_epoch_end_hooks:
          epoch_hook(
              self.__model,
              self.neural_module,
              epoch,
              validation_metrics,
          )
      if len(validation_metrics) > 0:
          self.LOGGER.info(
              "Validation Metrics: %s",
              json.dumps(validation_metrics, indent=2),
          )
  
      if self._target_metric is not None:
          target_metric = validation_metrics[self._target_metric]
      else:
          target_metric = validation_loss
  
      if self._target_metric_higher_is_better:
          target_metric_improved = target_metric > best_target_metric
      else:
          target_metric_improved = target_metric < best_target_metric
  
      return target_metric, target_metric_improved, validation_metrics
  
imports: from typing_extensions import Final, Protocol
  import json
  import logging
  import math
  import time
  import torch
  from pathlib import Path
  from tqdm import tqdm
  from typing import Callable, Dict, Generic, Iterable, List, Optional, TypeVar
  from ptgnn.baseneuralmodel.abstractneuralmodel import AbstractNeuralModel
  from ptgnn.baseneuralmodel.modulewithmetrics import ModuleWithMetrics
  from ptgnn.baseneuralmodel.utils.data import MemorizedDataIterable
  from ptgnn.baseneuralmodel.utils.oom import catch_cuda_oom
label_desc: Use image node_id 15 for calling the ModelTrainer obj's underlying member method code with example usage: obj._run_validation(validation_tensors, epoch, best_target_metric, device, parallelize, show_progress_bar) and returns: target_metric,  target_metric_improved,  validation_metrics