class_docstr: MetricReporter is responsible of three things:
  
  #. Aggregate output from trainer, which includes model inputs, predictions,
     targets, scores, and loss.
  #. Calculate metrics using the aggregated output, and define how the metric
     is used to find best model
  #. Optionally report the metrics and aggregated output to various channels
  
  Attributes:
      lower_is_better (bool): Whether a lower metric indicates better performance.
          Set to True for e.g. perplexity, and False for e.g. accuracy. Default
          is False
      channels (List[Channel]): A list of Channel that will receive metrics and
          the aggregated trainer output then format and report them in any customized
          way.
  
  MetricReporter is tightly-coupled with metric aggregation and computation which
  makes inheritance hard to reuse the parent functionalities and attributes. Next
  step is to decouple the metric aggregation and computation vs metric reporting.
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)
      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))
      self.batch_size.append(len(m_input[0]))
  
      # realtime stats
      if DatasetFieldName.NUM_TOKENS in context:
          self.realtime_meters["tps"].update(
              context[DatasetFieldName.NUM_TOKENS]
          )
          self.realtime_meters["ups"].update(1)
  
imports: from typing import Dict, List
  import numpy
  import torch
  from pytext.common.constants import BatchContext, DatasetFieldName, RawExampleFieldName, Stage
  from pytext.config.component import Component, ComponentType
  from pytext.config.pytext_config import ConfigBase
  from pytext.metric_reporters.channel import Channel, ConsoleChannel
  from pytext.metrics import RealtimeMetrics
  from pytext.utils import cuda
  from pytext.utils.meter import TimeMeter
label_desc: Use image node_id 4 for calling the MetricReporter obj's underlying member method code with example usage: obj.add_batch_stats(n_batches, preds, targets, scores, loss, m_input) without return types