class_docstr: Encapsulates an existing nn.Module to make it subclass MultiTaskModule,
  the user should still be able to interact with the encapsulated module
  as if it was the module itself.
  
  The only things that change are the following, the classifier from the
  given model will be replaced by a MultiHeadClassifier, and the forward()
  implementation will be overwritten by one that accepts task labels.
  The encapsulated module will then be automatically extended to
  fit new classes during calls to model.adaptation()
docstr: :param model: pytorch nn.Module that does not support multitask
  :param classifier_name: attribute name of the existing classification
                          layer inside the module
docstr_tok: [":","param","model",":","pytorch","nn.Module","that","does","not","support","multitask",":","param","classifier_name",":","attribute","name","of","the","existing","classification","layer","inside","the","module"]
code: def __init__(self, model: nn.Module, classifier_name: str):
      """
      :param model: pytorch nn.Module that does not support multitask
      :param classifier_name: attribute name of the existing classification
                              layer inside the module
      """
      for m in model.modules():
          assert not isinstance(m, MultiTaskModule)
  
      self.__dict__["_initialized"] = False
      super().__init__()
      self.model = model
      self.classifier_name = classifier_name
  
      old_classifier = getattr(model, classifier_name)
  
      if isinstance(old_classifier, nn.Linear):
          in_size = old_classifier.in_features
          out_size = old_classifier.out_features
          old_params = [
              torch.clone(p.data) for p in old_classifier.parameters()
          ]
          # Replace old classifier by empty block
          setattr(self.model, classifier_name, nn.Sequential())
      elif isinstance(old_classifier, nn.Sequential):
          in_size = old_classifier[-1].in_features
          out_size = old_classifier[-1].out_features
          old_params = [
              torch.clone(p.data)
              for p in old_classifier[-1].parameters()
          ]
          del old_classifier[-1]
      else:
          raise NotImplementedError(
              f"Cannot handle the following type \
              of classification layer {type(old_classifier)}"
          )
  
      # Set new classifier and initialize to previous param values
      setattr(
          self, classifier_name, MultiHeadClassifier(in_size, out_size)
      )
  
      for param, param_old in zip(
          getattr(self, classifier_name).parameters(), old_params
      ):
          param.data = param_old
  
      self.max_class_label = max(self.max_class_label, out_size)
      self._initialized = True
  
file_path: avalanche/avalanche/models/helper_method.py
imports: import torch
  import torch.nn
  from avalanche.models.dynamic_modules import MultiTaskModule, MultiHeadClassifier
label_desc: Use image node_id 1 to create a new MultiTaskDecorator object from inherited base classes: MultiTaskModule with example: obj = MultiTaskDecorator(model, classifier_name)