class_docstr: A training loop.
class_docstr_tok: ["A","training","loop","."]
docstr: Run one epoch.
  
  :param batches:
      the batches to process
  :param callbacks:
      the callbacks to apply (wrapped into a single object)
  :param sub_batch_size:
      the sub-batch size to use
  :param label_smoothing:
      the label-smoothing to apply
  :param slice_size:
      the optional slice size
  :param epoch:
      the current epoch (only used to forward to callbacks)
  :param only_size_probing:
      whether to stop after the second batch
  :param backward:
      whether to calculate gradients via backward
  
  :return:
      the epoch loss
docstr_tok: ["Run","one","epoch",".",":","param","batches",":","the","batches","to","process",":","param","callbacks",":","the","callbacks","to","apply","(","wrapped","into","a","single","object",")",":","param","sub_batch_size",":","the","sub-batch","size","to","use",":","param","label_smoothing",":","the","label-smoothing","to","apply",":","param","slice_size",":","the","optional","slice","size",":","param","epoch",":","the","current","epoch","(","only","used","to","forward","to","callbacks",")",":","param","only_size_probing",":","whether","to","stop","after","the","second","batch",":","param","backward",":","whether","to","calculate","gradients","via","backward",":","return",":","the","epoch","loss"]
code: def _train_epoch(
      self,
      batches: DataLoader,
      callbacks: MultiTrainingCallback,
      sub_batch_size: Optional[int],
      label_smoothing: float,
      slice_size: Optional[int],
      epoch: int,
      only_size_probing: bool,
      backward: bool = True,
  ) -> float:
      """
      Run one epoch.
  
      :param batches:
          the batches to process
      :param callbacks:
          the callbacks to apply (wrapped into a single object)
      :param sub_batch_size:
          the sub-batch size to use
      :param label_smoothing:
          the label-smoothing to apply
      :param slice_size:
          the optional slice size
      :param epoch:
          the current epoch (only used to forward to callbacks)
      :param only_size_probing:
          whether to stop after the second batch
      :param backward:
          whether to calculate gradients via backward
  
      :return:
          the epoch loss
      """
      # Accumulate loss over epoch
      current_epoch_loss = 0.0
  
      # Flag to check when to quit the size probing
      evaluated_once = False
  
      for batch in batches:
          # apply callbacks before starting with batch
          callbacks.pre_batch()
  
          # Get batch size of current batch (last batch may be incomplete)
          current_batch_size = self._get_batch_size(batch)
          _sub_batch_size = sub_batch_size or current_batch_size
  
          # accumulate gradients for whole batch
          for start in range(0, current_batch_size, _sub_batch_size):
              stop = min(start + _sub_batch_size, current_batch_size)
  
              # forward pass call
              batch_loss = self._forward_pass(
                  batch,
                  start,
                  stop,
                  current_batch_size,
                  label_smoothing,
                  slice_size,
                  backward=backward,
              )
              current_epoch_loss += batch_loss
              callbacks.on_batch(
                  epoch=epoch, batch=batch, batch_loss=batch_loss
              )
  
          callbacks.pre_step()
          callbacks.post_batch(epoch=epoch, batch=batch)
  
          # For testing purposes we're only interested in processing one batch
          if only_size_probing and evaluated_once:
              break
          evaluated_once = True
  
      # note: this epoch loss can be slightly biased towards the last batch, if this is smaller than the rest
      #        in practice, this should have a minor effect, since typically batch_size << num_instances
      current_epoch_loss = current_epoch_loss / len(batches)
  
      # TODO: is this necessary?
      del batch
      del batches
      gc.collect()
      self.optimizer.zero_grad()
      self._free_graph_and_cache()
  
      return current_epoch_loss
  
imports: import gc
  import logging
  import os
  import pathlib
  import pickle
  import random
  import time
  from abc import ABC, abstractmethod
  from contextlib import ExitStack
  from datetime import datetime
  from hashlib import md5
  from tempfile import NamedTemporaryFile, TemporaryDirectory
  from typing import IO, Any, ClassVar, Generic, List, Mapping, Optional, Tuple, TypeVar, Union
  import numpy
  import torch
  from class_resolver import HintOrType, OptionalKwargs
  from class_resolver.contrib.torch import lr_scheduler_resolver, optimizer_resolver
  from torch.optim.optimizer import Optimizer
  from torch.utils.data import DataLoader
  from tqdm.autonotebook import tqdm, trange
  from .callbacks import GradientAbsClippingTrainingCallback, GradientNormClippingTrainingCallback, LearningRateSchedulerTrainingCallback, MultiTrainingCallback, OptimizerTrainingCallback, StopperTrainingCallback, TrackerTrainingCallback, TrainingCallback, TrainingCallbackHint, TrainingCallbackKwargsHint
  from ..constants import PYKEEN_CHECKPOINTS, PYKEEN_DEFAULT_CHECKPOINT
  from ..lr_schedulers import LRScheduler
  from ..models import RGCN, Model
  from ..stoppers import Stopper
  from ..trackers import ResultTracker, tracker_resolver
  from ..triples import CoreTriplesFactory, TriplesFactory
  from ..typing import InductiveMode
  from ..utils import format_relative_comparison, get_batchnorm_modules, get_preferred_device, is_cuda_oom_error, is_cudnn_error, normalize_string
label_desc: Use image node_id 7 for calling the TrainingLoop obj's underlying member method code with example usage: obj._train_epoch(batches, callbacks, sub_batch_size, label_smoothing, slice_size, epoch, only_size_probing, backward) and returns: current_epoch_loss