class_docstr: ER AML, as proposed in
  "New Insights on Reducing Abrupt Representation
  Change in Online Continual Learning"
  by Lucas Caccia et. al.
  https://openreview.net/forum?id=N8MaByOzUfb
class_docstr_tok: ["ER","AML",",","as","proposed","in","''","New","Insights","on","Reducing","Abrupt","Representation","Change","in","Online","Continual","Learning","''","by","Lucas","Caccia","et",".","al",".","https",":","\/\/openreview.net\/forum","?","id=N8MaByOzUfb"]
docstr: Training epoch.
  
  :param kwargs:
  :return:
docstr_tok: ["Training","epoch",".",":","param","kwargs",":",":","return",":"]
code: def training_epoch(self, **kwargs):
      """Training epoch.
  
      :param kwargs:
      :return:
      """
      for self.mbatch in self.dataloader:
          if self._stop_training:
              break
  
          self._unpack_minibatch()
          self._before_training_iteration(**kwargs)
  
          if self.replay_loader is not None:
              (
                  self.mb_buffer_x,
                  self.mb_buffer_y,
                  self.mb_buffer_tid,
              ) = next(self.replay_loader)
              self.mb_buffer_x, self.mb_buffer_y, self.mb_buffer_tid = (
                  self.mb_buffer_x.to(self.device),
                  self.mb_buffer_y.to(self.device),
                  self.mb_buffer_tid.to(self.device),
              )
  
          self.optimizer.zero_grad()
          self.loss = self._make_empty_loss()
  
          # Forward
          self._before_forward(**kwargs)
          self.mb_output = self.forward()
          if self.replay_loader is not None:
              self.mb_buffer_out = avalanche_forward(
                  self.model, self.mb_buffer_x, self.mb_buffer_tid
              )
          self._after_forward(**kwargs)
  
          # Loss & Backward
          if self.replay_loader is None:
              self.loss += self.criterion()
          else:
              pos_neg_replay = tuple(
                  torch.cat(samples)
                  for samples in zip(
                      *[next(loader) for loader in self.pos_neg_loaders]
                  )
              )
              self.loss += self.aml_criterion(
                  self.mb_x,
                  self.mb_y,
                  self.mb_task_id,
                  self.mb_buffer_out,
                  self.mb_buffer_y,
                  pos_neg_replay,
              )
  
          self._before_backward(**kwargs)
          self.backward()
          self._after_backward(**kwargs)
  
          # Optimization step
          self._before_update(**kwargs)
          self.optimizer_step()
          self._after_update(**kwargs)
  
          self._after_training_iteration(**kwargs)
  
file_path: avalanche/avalanche/training/supervised/er_aml.py
imports: from typing import Callable, List, Optional, Union
  import torch
  from torch.nn import CrossEntropyLoss, Module
  from torch.optim import Optimizer
  from avalanche.core import SupervisedPlugin
  from avalanche.models.utils import avalanche_forward
  from avalanche.training import AMLCriterion
  from avalanche.training.plugins.evaluation import EvaluationPlugin, default_evaluator
  from avalanche.training.storage_policy import ClassBalancedBuffer
  from avalanche.training.templates import SupervisedTemplate
  from avalanche.training.utils import cycle
label_desc: Use image node_id 2 for calling the ER_AML obj's underlying member method code with example usage: obj.training_epoch() without return types