class_docstr: Abstract class for custom training or validation loops.
  
  The scheduler will only be called at a batch or epoch frequency, depending
  on the user parameter. Be sure to set ``scheduler_step_freq`` in
  ``TorchTrainer`` to either "batch" or "epoch" to increment the scheduler
  correctly during training. If using a learning rate scheduler
  that depends on validation loss, you can use ``trainer.update_scheduler``.
  
  For both training and validation, there are two granularities that
  you can provide customization: per epoch or per batch.
  You do not need to override both.
  
  .. image:: raysgd-custom.jpg
      :scale: 80%
      :align: center
  
  Raises:
      ValueError if multiple models/optimizers/schedulers are provided.
          You are expected to subclass this class if you wish
          to train over multiple models/optimizers/schedulers.
code: def _train_loop(self, iterator, info, _progress_bar, metric_meters):
      for batch_idx, batch in enumerate(iterator):
          batch_info = {
              "batch_idx": batch_idx,
              "global_step": self.global_step,
          }
          batch_info.update(info)
          metrics = self.train_batch(batch, batch_info=batch_info)
  
          if self.use_tqdm and self.world_rank == 0:
              _progress_bar.n = batch_idx + 1
              postfix = {}
              if "train_loss" in metrics:
                  postfix.update(loss=metrics["train_loss"])
              _progress_bar.set_postfix(postfix)
  
          if (
              self.scheduler
              and batch_info.get(SCHEDULER_STEP) == SCHEDULER_STEP_BATCH
          ):
              self.scheduler.step()
  
          metric_meters.update(metrics, n=metrics.pop(NUM_SAMPLES, 1))
          self.global_step += 1
  
imports: import collections
  import torch
  import numpy
  from zoo.orca.learn.metrics import Metric
  from zoo.orca.learn.pytorch.utils import TimerCollection, AverageMeterCollection, NUM_SAMPLES
  from zoo.orca.learn.pytorch.constants import SCHEDULER_STEP_EPOCH, NUM_STEPS, SCHEDULER_STEP_BATCH, SCHEDULER_STEP
  from torch.nn.parallel import DistributedDataParallel
label_desc: Use image node_id 5 for calling the TrainingOperator obj's underlying member method code with example usage: obj._train_loop(iterator, info, _progress_bar, metric_meters) without return types