class_docstr: Updates NCM prototypes
  using all the data seen so far
  WARNING: This is an oracle,
  and thus breaks assumptions usually made
  in continual learning algorithms i
  (storage of full dataset)
  This is meant to be used as an upper bound
  for NCM based methods
  (i.e when trying to estimate prototype drift)
class_docstr_tok: ["Updates","NCM","prototypes","using","all","the","data","seen","so","far","WARNING",":","This","is","an","oracle",",","and","thus","breaks","assumptions","usually","made","in","continual","learning","algorithms","i","(","storage","of","full","dataset",")","This","is","meant","to","be","used","as","an","upper","bound","for","NCM","based","methods","(","i.e","when","trying","to","estimate","prototype","drift",")"]
code: def after_training_exp(self, strategy, **kwargs):
      _check_has_ncm(strategy.model)
      self.all_datasets.append(strategy.experience.dataset)
      accumulated_dataset = concat_datasets(self.all_datasets)
  
      class_means_dict = compute_class_means(
          strategy.model,
          accumulated_dataset,
          strategy.train_mb_size,
          normalize=strategy.model.eval_classifier.normalize,
          device=strategy.device,
      )
  
      strategy.model.eval_classifier.replace_class_means_dict(
          class_means_dict
      )
  
imports: import collections
  import copy
  from typing import Dict
  import numpy
  import torch
  import torch.nn.functional
  import tqdm
  from torch import Tensor, nn
  from avalanche.benchmarks.utils import concat_datasets
  from avalanche.training.plugins import SupervisedPlugin
  from avalanche.training.storage_policy import ClassBalancedBuffer
  from avalanche.training.templates import SupervisedTemplate
  from avalanche.models import NCMClassifier
label_desc: Use image node_id 2 for calling the NCMOracle obj's underlying member method code with example usage: obj.after_training_exp(strategy) without return types