docstr: Gets called at the end of a epoch.
docstr_tok: ["Gets","called","at","the","end","of","a","epoch","."]
code: def on_stage_end(self, stage, stage_loss, epoch):
      """Gets called at the end of a epoch."""
      # Compute/store important stats
      if stage == sb.Stage.TRAIN:
          self.train_stats = stage_loss
  
      else:  # valid or test
          stage_stats = {"loss": stage_loss}
          stage_stats["ACC"] = self.acc_metric.summarize()
          current_epoch = self.hparams.epoch_counter.current
          valid_search_interval = self.hparams.valid_search_interval
          if (
              current_epoch % valid_search_interval == 0
              and self.optimizer_step >= 1000
              or stage == sb.Stage.TEST
          ):
              stage_stats["BLEU"] = self.bleu_metric.summarize(
                  field="BLEU"
              )
              stage_stats[
                  "BLEU_extensive"
              ] = self.bleu_metric.summarize()
              self.anneal_bleu = stage_stats["BLEU"]
  
      # log stats and save checkpoint at end-of-epoch
      if (
          stage == sb.Stage.VALID
          and sb.utils.distributed.if_main_process()
      ):
          current_epoch = self.hparams.epoch_counter.current
          old_lr_adam, new_lr_adam = self.hparams.lr_annealing_adam(
              self.anneal_bleu  # stage_stats["BLEU"]
          )
          sb.nnet.schedulers.update_learning_rate(
              self.adam_optimizer, new_lr_adam
          )
  
          stats_meta = {
              "epoch": current_epoch,
              "steps": self.optimizer_step,
              "lr_adam": old_lr_adam,
          }
  
          if not self.hparams.wav2vec2_frozen:
              self.hparams.lr_annealing_wav2vec(
                  self.wav2vec_optimizer, self.optimizer_step
              )
              stats_meta[
                  "lr_wav2vec"
              ] = self.wav2vec_optimizer.param_groups[0]["lr"]
          if not self.hparams.mbart_frozen:
              self.hparams.lr_annealing_mbart(
                  self.mbart_optimizer, self.optimizer_step
              )
              stats_meta[
                  "lr_mbart"
              ] = self.mbart_optimizer.param_groups[0]["lr"]
          self.hparams.train_logger.log_stats(
              stats_meta=stats_meta,
              train_stats={"loss": self.train_stats},
              valid_stats=stage_stats,
          )
  
          # create checkpoing
          valid_search_interval = self.hparams.valid_search_interval
          if (
              current_epoch % valid_search_interval == 0
              and self.optimizer_step >= 1000
          ):
              meta = {
                  "BLEU": stage_stats["BLEU"],
                  "epoch": current_epoch,
              }
              name = "checkpoint_epoch" + str(current_epoch)
  
              self.checkpointer.save_and_keep_only(
                  meta=meta,
                  name=name,
                  num_to_keep=10,
                  max_keys=["BLEU"],
              )
  
      elif stage == sb.Stage.TEST:
          self.hparams.train_logger.log_stats(
              stats_meta={
                  "Epoch loaded": self.hparams.epoch_counter.current
              },
              test_stats=stage_stats,
          )
  
          with open(self.hparams.bleu_file, "w") as w:
              self.bleu_metric.write_stats(w)
  
file_path: speechbrain/recipes/IWSLT22_lowresource/AST/transformer/train_with_w2v_mbart.py
imports: import sys
  import torch
  import logging
  import speechbrain
  from speechbrain.utils.distributed import run_on_main
  from hyperpyyaml import load_hyperpyyaml
  from sacremoses import MosesDetokenizer
  from torch.nn.parallel import DistributedDataParallel
label_desc: Use image node_id 6 for calling the ST obj's underlying member method code with example usage: obj.on_stage_end(stage, stage_loss, epoch) without return types