class_docstr: Base class for continual learning skeletons.
  
  **Training loop**
  The training loop is organized as follows::
  
      train
          train_exp  # for each experience
  
  **Evaluation loop**
  The evaluation loop is organized as follows::
  
      eval
          eval_exp  # for each experience
class_docstr_tok: ["Base","class","for","continual","learning","skeletons",".","*","*","Training","loop","*","*","The","training","loop","is","organized","as","follows",":",":","train","train_exp","#","for","each","experience","*","*","Evaluation","loop","*","*","The","evaluation","loop","is","organized","as","follows",":",":","eval","eval_exp","#","for","each","experience"]
docstr: Training loop.
  
  If experiences is a single element trains on it.
  If it is a sequence, trains the model on each experience in order.
  This is different from joint training on the entire stream.
  It returns a dictionary with last recorded value for each metric.
  
  :param experiences: single Experience or sequence.
  :param eval_streams: sequence of streams for evaluation.
      If None: use training experiences for evaluation.
      Use [] if you do not want to evaluate during training.
      Experiences in `eval_streams` are grouped by stream name
      when calling `eval`. If you use multiple streams, they must
      have different names.
docstr_tok: ["Training","loop",".","If","experiences","is","a","single","element","trains","on","it",".","If","it","is","a","sequence",",","trains","the","model","on","each","experience","in","order",".","This","is","different","from","joint","training","on","the","entire","stream",".","It","returns","a","dictionary","with","last","recorded","value","for","each","metric",".",":","param","experiences",":","single","Experience","or","sequence",".",":","param","eval_streams",":","sequence","of","streams","for","evaluation",".","If","None",":","use","training","experiences","for","evaluation",".","Use","[","]","if","you","do","not","want","to","evaluate","during","training",".","Experiences","in","`","eval_streams","`","are","grouped","by","stream","name","when","calling","`","eval","`",".","If","you","use","multiple","streams",",","they","must","have","different","names","."]
code: def train(
      self,
      experiences: Union[TExperienceType, Iterable[TExperienceType]],
      eval_streams: Optional[
          Sequence[Union[TExperienceType, Iterable[TExperienceType]]]
      ] = None,
      **kwargs,
  ):
      """Training loop.
  
      If experiences is a single element trains on it.
      If it is a sequence, trains the model on each experience in order.
      This is different from joint training on the entire stream.
      It returns a dictionary with last recorded value for each metric.
  
      :param experiences: single Experience or sequence.
      :param eval_streams: sequence of streams for evaluation.
          If None: use training experiences for evaluation.
          Use [] if you do not want to evaluate during training.
          Experiences in `eval_streams` are grouped by stream name
          when calling `eval`. If you use multiple streams, they must
          have different names.
      """
      if not self._distributed_check:
          # Checks if the strategy elements are compatible with
          # distributed training
          self._check_distributed_training_compatibility()
          self._distributed_check = True
  
      self.is_training = True
      self._stop_training = False
  
      self.model.train()
      self.model.to(self.device)
  
      # Normalize training and eval data.
      experiences_list: Iterable[
          TExperienceType
      ] = _experiences_parameter_as_iterable(experiences)
  
      if eval_streams is None:
          eval_streams = [experiences_list]
  
      self._eval_streams = _group_experiences_by_stream(eval_streams)
  
      self._before_training(**kwargs)
  
      for self.experience in experiences_list:
          self._before_training_exp(**kwargs)
          self._train_exp(self.experience, eval_streams, **kwargs)
          self._after_training_exp(**kwargs)
      self._after_training(**kwargs)
      self._train_cleanup()
  
imports: import sys
  import warnings
  from collections import defaultdict
  from typing import Iterable, Sequence, Optional, TypeVar, Union, List
  import torch
  from torch.nn import Module
  from avalanche.benchmarks import CLExperience, CLStream
  from avalanche.core import BasePlugin
  from avalanche.distributed.distributed_helper import DistributedHelper
  from avalanche.training.templates.strategy_mixin_protocol import BaseStrategyProtocol
  from avalanche.training.utils import trigger_plugins
label_desc: Use image node_id 3 for calling the BaseTemplate obj's underlying member method code with example usage: obj.train(experiences, eval_streams) without return types