class_docstr: The standalone confusion matrix metric.
  
  Instances of this metric keep track of the confusion matrix by receiving a
  pair of "ground truth" and "prediction" Tensors describing the labels of a
  minibatch. Those two tensors can both contain plain labels or
  one-hot/logit vectors.
  
  The result is the unnormalized running confusion matrix.
  
  Beware that by default the confusion matrix size will depend on the value of
  the maximum label as detected by looking at both the ground truth and
  predictions Tensors. When passing one-hot/logit vectors, this
  metric will try to infer the number of classes from the vector sizes.
  Otherwise, the maximum label value encountered in the truth/prediction
  Tensors will be used.
  
  If the user sets the `num_classes`, then the confusion matrix will always be
  of size `num_classes, num_classes`. Whenever a prediction or label tensor is
  provided as logits, only the first `num_classes` units will be considered in
  the confusion matrix computation. If they are provided as numerical labels,
  each of them has to be smaller than `num_classes`.
  
  The reset method will bring the metric to its initial state. By default
  this metric in its initial state will return an empty Tensor.
class_docstr_tok: ["The","standalone","confusion","matrix","metric",".","Instances","of","this","metric","keep","track","of","the","confusion","matrix","by","receiving","a","pair","of","``","ground","truth","''","and","``","prediction","''","Tensors","describing","the","labels","of","a","minibatch",".","Those","two","tensors","can","both","contain","plain","labels","or","one-hot\/logit","vectors",".","The","result","is","the","unnormalized","running","confusion","matrix",".","Beware","that","by","default","the","confusion","matrix","size","will","depend","on","the","value","of","the","maximum","label","as","detected","by","looking","at","both","the","ground","truth","and","predictions","Tensors",".","When","passing","one-hot\/logit","vectors",",","this","metric","will","try","to","infer","the","number","of","classes","from","the","vector","sizes",".","Otherwise",",","the","maximum","label","value","encountered","in","the","truth\/prediction","Tensors","will","be","used",".","If","the","user","sets","the","`","num_classes","`",",","then","the","confusion","matrix","will","always","be","of","size","`","num_classes",",","num_classes","`",".","Whenever","a","prediction","or","label","tensor","is","provided","as","logits",",","only","the","first","`","num_classes","`","units","will","be","considered","in","the","confusion","matrix","computation",".","If","they","are","provided","as","numerical","labels",",","each","of","them","has","to","be","smaller","than","`","num_classes","`",".","The","reset","method","will","bring","the","metric","to","its","initial","state",".","By","default","this","metric","in","its","initial","state","will","return","an","empty","Tensor","."]
docstr: Update the running confusion matrix given the true and predicted labels.
  
  :param true_y: The ground truth. Both labels and one-hot vectors
      are supported.
  :param predicted_y: The ground truth. Both labels and logit vectors
      are supported.
  :return: None.
docstr_tok: ["Update","the","running","confusion","matrix","given","the","true","and","predicted","labels",".",":","param","true_y",":","The","ground","truth",".","Both","labels","and","one-hot","vectors","are","supported",".",":","param","predicted_y",":","The","ground","truth",".","Both","labels","and","logit","vectors","are","supported",".",":","return",":","None","."]
code: def update(self, true_y: Tensor, predicted_y: Tensor) -> None:
      """
      Update the running confusion matrix given the true and predicted labels.
  
      :param true_y: The ground truth. Both labels and one-hot vectors
          are supported.
      :param predicted_y: The ground truth. Both labels and logit vectors
          are supported.
      :return: None.
      """
      if len(true_y) != len(predicted_y):
          raise ValueError(
              "Size mismatch for true_y and predicted_y tensors"
          )
  
      if len(true_y.shape) > 2:
          raise ValueError(
              "Confusion matrix supports labels with at"
              " most 2 dimensions"
          )
      if len(predicted_y.shape) > 2:
          raise ValueError(
              "Confusion matrix supports predictions with at "
              "most 2 dimensions"
          )
  
      max_label = (
          -1 if self._num_classes is None else self._num_classes - 1
      )
  
      # SELECT VALID PORTION OF TARGET AND PREDICTIONS
      true_y = torch.as_tensor(true_y)
      if len(true_y.shape) == 2 and self._num_classes is not None:
          true_y = true_y[:, : max_label + 1]
      predicted_y = torch.as_tensor(predicted_y)
      if len(predicted_y.shape) == 2 and self._num_classes is not None:
          predicted_y = predicted_y[:, : max_label + 1]
  
      # COMPUTE MAX LABEL AND CONVERT TARGET AND PREDICTIONS IF NEEDED
      if len(predicted_y.shape) > 1:
          # Logits -> transform to labels
          if self._num_classes is None:
              max_label = max(max_label, predicted_y.shape[1] - 1)
          predicted_y = torch.max(predicted_y, 1)[1]
      else:
          # Labels -> check non-negative
          min_label = torch.min(predicted_y).item()
          if min_label < 0:
              raise ValueError(
                  "Label values must be non-negative values"
              )
          if self._num_classes is None:
              max_label = max(max_label, torch.max(predicted_y).item())
          elif torch.max(predicted_y).item() >= self._num_classes:
              raise ValueError(
                  "Encountered predicted label larger than"
                  "num_classes"
              )
  
      if len(true_y.shape) > 1:
          # Logits -> transform to labels
          if self._num_classes is None:
              max_label = max(max_label, true_y.shape[1] - 1)
          true_y = torch.max(true_y, 1)[1]
      else:
          # Labels -> check non-negative
          min_label = torch.min(true_y).item()
          if min_label < 0:
              raise ValueError(
                  "Label values must be non-negative values"
              )
  
          if self._num_classes is None:
              max_label = max(max_label, torch.max(true_y).item())
          elif torch.max(true_y).item() >= self._num_classes:
              raise ValueError(
                  "Encountered target label larger than" "num_classes"
              )
  
      if max_label < 0:
          raise ValueError(
              "The Confusion Matrix metric can only handle "
              "positive label values"
          )
  
      if self._cm_tensor is None:
          # Create the confusion matrix
          self._cm_tensor = torch.zeros(
              (max_label + 1, max_label + 1), dtype=torch.long
          )
      elif max_label >= self._cm_tensor.shape[0]:
          # Enlarge the confusion matrix
          size_diff = 1 + max_label - self._cm_tensor.shape[0]
          self._cm_tensor = pad(
              self._cm_tensor, (0, size_diff, 0, size_diff)
          )
  
      for pattern_idx in range(len(true_y)):
          self._cm_tensor[true_y[pattern_idx]][
              predicted_y[pattern_idx]
          ] += 1
  
imports: from matplotlib.figure import Figure
  from numpy import arange
  from typing_extensions import Literal
  from typing import Any, Callable, Iterable, Union, Optional, TYPE_CHECKING, List
  import wandb
  import numpy
  import torch
  from PIL.Image import Image
  from torch import Tensor
  from torch.nn.functional import pad
  from avalanche.benchmarks import NCScenario
  from avalanche.evaluation import PluginMetric, Metric
  from avalanche.evaluation.metric_results import AlternativeValues, MetricValue, MetricResult
  from avalanche.evaluation.metric_utils import default_cm_image_creator, phase_and_task, stream_type
label_desc: Use image node_id 2 for calling the ConfusionMatrix obj's underlying member method code with example usage: obj.update(true_y, predicted_y) without return types