docstr: Gets called at the end of an epoch.
  Arguments
  ---------
  stage : sb.Stage
      One of sb.Stage.TRAIN, sb.Stage.VALID, sb.Stage.TEST
  stage_loss : float
      The average loss for all of the data processed in this stage.
  epoch : int
      The currently-starting epoch. This is passed
      `None` during the test stage.
docstr_tok: ["Gets","called","at","the","end","of","an","epoch",".","Arguments","--","--","--","--","-","stage",":","sb.Stage","One","of","sb.Stage.TRAIN",",","sb.Stage.VALID",",","sb.Stage.TEST","stage_loss",":","float","The","average","loss","for","all","of","the","data","processed","in","this","stage",".","epoch",":","int","The","currently-starting","epoch",".","This","is","passed","`","None","`","during","the","test","stage","."]
code: def on_stage_end(self, stage, stage_loss, epoch):
      """Gets called at the end of an epoch.
      Arguments
      ---------
      stage : sb.Stage
          One of sb.Stage.TRAIN, sb.Stage.VALID, sb.Stage.TEST
      stage_loss : float
          The average loss for all of the data processed in this stage.
      epoch : int
          The currently-starting epoch. This is passed
          `None` during the test stage.
      """
      # At the end of validation, we can write
      if stage == sb.Stage.VALID:
          # Update learning rate
          self.last_epoch = epoch
          lr = self.hparams.noam_annealing.current_lr
  
          # The train_logger writes a summary to stdout and to the logfile.
          self.hparams.train_logger.log_stats(  # 1#2#
              stats_meta={"Epoch": epoch, "lr": lr},
              train_stats=self.last_loss_stats[sb.Stage.TRAIN],
              valid_stats=self.last_loss_stats[sb.Stage.VALID],
          )
          output_progress_sample = (
              self.hparams.progress_samples
              and epoch % self.hparams.progress_samples_interval == 0
              and epoch >= self.hparams.progress_samples_min_run
          )
  
          if output_progress_sample:
              logger.info("Saving predicted samples")
              (
                  inference_mel,
                  mel_lens,
                  inf_mel_spn_pred,
                  mel_lens_spn_pred,
              ) = self.run_inference()
              self.hparams.progress_sample_logger.save(epoch)
              self.run_vocoder(
                  inference_mel, mel_lens, sample_type="with_spn"
              )
              self.run_vocoder(
                  inf_mel_spn_pred,
                  mel_lens_spn_pred,
                  sample_type="no_spn",
              )
          # Save the current checkpoint and delete previous checkpoints.
          # UNCOMMENT THIS
          self.checkpointer.save_and_keep_only(
              meta=self.last_loss_stats[stage],
              min_keys=["total_loss"],
          )
      # We also write statistics about test data spectogramto stdout and to the logfile.
      if stage == sb.Stage.TEST:
          self.hparams.train_logger.log_stats(
              {"Epoch loaded": self.hparams.epoch_counter.current},
              test_stats=self.last_loss_stats[sb.Stage.TEST],
          )
  
imports: import os
  import sys
  import torch
  import logging
  import torchaudio
  import numpy
  import speechbrain
  from speechbrain.inference.vocoders import HIFIGAN
  from pathlib import Path
  from hyperpyyaml import load_hyperpyyaml
  from speechbrain.utils.data_utils import scalarize
  from speechbrain.inference.text import GraphemeToPhoneme
label_desc: Use image node_id 7 for calling the FastSpeech2Brain obj's underlying member method code with example usage: obj.on_stage_end(stage, stage_loss, epoch) without return types