class_docstr: Neural HMM TTS model.
  
  Paper::
      https://arxiv.org/abs/2108.13320
  
  Paper abstract::
      Neural sequence-to-sequence TTS has achieved significantly better output quality
  than statistical speech synthesis using HMMs.However, neural TTS is generally not probabilistic
  and uses non-monotonic attention. Attention failures increase training time and can make
  synthesis babble incoherently. This paper describes how the old and new paradigms can be
  combined to obtain the advantages of both worlds, by replacing attention in neural TTS with
  an autoregressive left-right no-skip hidden Markov model defined by a neural network.
  Based on this proposal, we modify Tacotron 2 to obtain an HMM-based neural TTS model with
  monotonic alignment, trained to maximise the full sequence likelihood without approximation.
  We also describe how to combine ideas from classical and contemporary TTS for best results.
  The resulting example system is smaller and simpler than Tacotron 2, and learns to speak with
  fewer iterations and less data, whilst achieving comparable naturalness prior to the post-net.
  Our approach also allows easy control over speaking rate. Audio examples and code
  are available at https://shivammehta25.github.io/Neural-HMM/ .
  
  Note:
      - This is a parameter efficient version of OverFlow (15.3M vs 28.6M). Since it has half the
      number of parameters as OverFlow the synthesis output quality is suboptimal (but comparable to Tacotron2
      without Postnet), but it learns to speak with even lesser amount of data and is still significantly faster
      than other attention-based methods.
  
      - Neural HMMs uses flat start initialization i.e it computes the means and std and transition probabilities
      of the dataset and uses them to initialize the model. This benefits the model and helps with faster learning
      If you change the dataset or want to regenerate the parameters change the `force_generate_statistics` and
      `mel_statistics_parameter_path` accordingly.
  
      - To enable multi-GPU training, set the `use_grad_checkpointing=False` in config.
      This will significantly increase the memory usage.  This is because to compute
      the actual data likelihood (not an approximation using MAS/Viterbi) we must use
      all the states at the previous time step during the forward pass to decide the
      probability distribution at the current step i.e the difference between the forward
      algorithm and viterbi approximation.
  
  Check :class:`TTS.tts.configs.neuralhmm_tts_config.NeuralhmmTTSConfig` for class arguments.
code: def _training_stats(batch):
      stats = {}
      stats["avg_text_length"] = batch["text_lengths"].float().mean()
      stats["avg_spec_length"] = batch["mel_lengths"].float().mean()
      stats["avg_text_batch_occupancy"] = (
          batch["text_lengths"].float()
          / batch["text_lengths"].float().max()
      ).mean()
      stats["avg_spec_batch_occupancy"] = (
          batch["mel_lengths"].float()
          / batch["mel_lengths"].float().max()
      ).mean()
      return stats
  
imports: import os
  from typing import Dict, List, Union
  import torch
  from coqpit import Coqpit
  from torch import nn
  from trainer.logging.tensorboard_logger import TensorboardLogger
  from TTS.tts.layers.overflow.common_layers import Encoder, OverflowUtils
  from TTS.tts.layers.overflow.neural_hmm import NeuralHMM
  from TTS.tts.layers.overflow.plotting_utils import get_spec_from_most_probable_state, plot_transition_probabilities_to_numpy
  from TTS.tts.models.base_tts import BaseTTS
  from TTS.tts.utils.speakers import SpeakerManager
  from TTS.tts.utils.text.tokenizer import TTSTokenizer
  from TTS.tts.utils.visual import plot_alignment, plot_spectrogram
  from TTS.utils.generic_utils import format_aux_input
  from TTS.utils.io import load_fsspec
label_desc: Use image node_id 7 for calling the NeuralhmmTTS obj's underlying member method code with example usage: obj._training_stats(batch) and returns: stats