class_docstr: BERT-based tagging model for ITN, inspired by LaserTagger approach.
  It maps spoken-domain input words to tags:
      KEEP, DELETE, or any of predefined replacement tags which correspond to a written-domain fragment.
  Example: one hundred thirty four -> _1 <DELETE> 3 4_
class_docstr_tok: ["BERT-based","tagging","model","for","ITN",",","inspired","by","LaserTagger","approach",".","It","maps","spoken-domain","input","words","to","tags",":","KEEP",",","DELETE",",","or","any","of","predefined","replacement","tags","which","correspond","to","a","written-domain","fragment",".","Example",":","one","hundred","thirty","four","-",">","_1","<","DELETE",">","3","4_"]
docstr: Called at the end of validation to aggregate outputs.
  :param outputs: list of individual outputs of each validation step.
docstr_tok: ["Called","at","the","end","of","validation","to","aggregate","outputs",".",":","param","outputs",":","list","of","individual","outputs","of","each","validation","step","."]
code: def on_validation_epoch_end(self):
      """
      Called at the end of validation to aggregate outputs.
      :param outputs: list of individual outputs of each validation step.
      """
      avg_loss = torch.stack(
          [x["val_loss"] for x in self.validation_step_outputs]
      ).mean()
  
      # calculate metrics and classification report
      # In our task recall = accuracy, and the recall column - is the per class accuracy
      (
          _,
          tag_accuracy,
          _,
          tag_report,
      ) = self.tag_classification_report.compute()
      (
          _,
          tag_multiword_accuracy,
          _,
          tag_multiword_report,
      ) = self.tag_multiword_classification_report.compute()
  
      (
          _,
          semiotic_accuracy,
          _,
          semiotic_report,
      ) = self.semiotic_classification_report.compute()
  
      logging.info("Total tag accuracy: " + str(tag_accuracy))
      logging.info(tag_report)
      logging.info(
          "Only multiword tag accuracy: " + str(tag_multiword_accuracy)
      )
      logging.info(tag_multiword_report)
  
      logging.info("Total semiotic accuracy: " + str(semiotic_accuracy))
      logging.info(semiotic_report)
  
      self.log("val_loss", avg_loss, prog_bar=True)
      self.log("tag accuracy", tag_accuracy)
      self.log("tag multiword accuracy", tag_multiword_accuracy)
      self.log("semiotic accuracy", semiotic_accuracy)
  
      self.tag_classification_report.reset()
      self.tag_multiword_classification_report.reset()
      self.semiotic_classification_report.reset()
  
      self.validation_step_outputs.clear()
  
imports: from time import perf_counter
  from typing import Dict, List, Optional
  import torch
  from omegaconf import DictConfig
  from pytorch_lightning import Trainer
  from nemo.collections.common.losses import CrossEntropyLoss
  from nemo.collections.nlp.data.text_normalization_as_tagging import ThutmoseTaggerDataset, ThutmoseTaggerTestDataset, bert_example, tagging
  from nemo.collections.nlp.data.text_normalization_as_tagging.utils import read_label_map, read_semiotic_classes
  from nemo.collections.nlp.metrics.classification_report import ClassificationReport
  from nemo.collections.nlp.models.nlp_model import NLPModel
  from nemo.collections.nlp.modules.common.token_classifier import TokenClassifier
  from nemo.collections.nlp.parts.utils_funcs import tensor2list
  from nemo.core.classes.common import PretrainedModelInfo, typecheck
  from nemo.core.neural_types import LogitsType, NeuralType
  from nemo.utils import logging
  from nemo.utils.decorators import experimental
label_desc: Use image node_id 8 for calling the ThutmoseTaggerModel obj's underlying member method code with example usage: obj.on_validation_epoch_end() without return types