docstr: Aggregates a batch of output data (predictions, scores, targets/true labels
  and loss).
  
  Args:
      n_batches (int): number of current batch
      preds (torch.Tensor): predictions of current batch
      targets (torch.Tensor): targets of current batch
      scores (torch.Tensor): scores of current batch
      loss (double): average loss of current batch
      m_input (Tuple[torch.Tensor, ...]): model inputs of current batch
      context (Dict[str, Any]): any additional context data, it could be
          either a list of data which maps to each example, or a single value
          for the batch
code: def add_batch_stats(
      self, n_batches, preds, targets, scores, loss, m_input, **context
  ):
      """
      Aggregates a batch of output data (predictions, scores, targets/true labels
      and loss).
  
      Args:
          n_batches (int): number of current batch
          preds (torch.Tensor): predictions of current batch
          targets (torch.Tensor): targets of current batch
          scores (torch.Tensor): scores of current batch
          loss (double): average loss of current batch
          m_input (Tuple[torch.Tensor, ...]): model inputs of current batch
          context (Dict[str, Any]): any additional context data, it could be
              either a list of data which maps to each example, or a single value
              for the batch
      """
      self.n_batches = n_batches
      self.aggregate_preds(preds, context)
      self.aggregate_targets(targets, context)
  
      # if we are running in memory efficient mode, then don't store all the scores
      # This list in general is the most memory hungry of all the data structures.
      # For a problem with 10K classes, we store 10K floats for every instance in
      # the epoch. This is bad.
      if not self.is_memory_efficient:
          self.aggregate_scores(scores)
  
      for key, val in context.items():
          if not (
              isinstance(val, torch.Tensor) or isinstance(val, List)
          ):
              continue
          if key not in self.all_context:
              self.all_context[key] = []
          self.aggregate_data(self.all_context[key], val)
      # some loss functions (eg: in NewBertRegressionTask) return a tensor
      # convert tensor to float
      if loss is not None:
          self.all_loss.append(float(loss))
      # append the size of the first tensor (should be the batch size)
      if isinstance(m_input, Generator):
          # first element without updating the initial iterator
          first = tee(m_input, 1)
          self.batch_size.append(len(first))
      else:
          self.batch_size.append(len(m_input[0]))
  
imports: from enum import Enum
  from itertools import tee, zip_longest
  from typing import Generator, List, Optional, Sequence
  import torch
  from pytext.common.constants import Stage
  from pytext.data import CommonMetadata
  from pytext.metrics import ClassificationMetrics, compute_classification_metrics, compute_multi_label_classification_metrics, LabelListPrediction, LabelPrediction, LabelTopKPrediction, RECALL_AT_PRECISION_THRESHOLDS, safe_division
  from pytext.metrics.intent_slot_metrics import PerLabelConfusions
  from .channel import Channel, ConsoleChannel, FileChannel
  from .metric_reporter import MetricReporter
label_desc: Use image node_id 6 for calling the ClassificationMetricReporter obj's underlying member method code with example usage: obj.add_batch_stats(n_batches, preds, targets, scores, loss, m_input) without return types