class_docstr: This class calculates Viterbi alignments in the forward method.
  
  It also records alignments and creates batches of them for use
  in Viterbi training.
  
  Arguments
  ---------
  states_per_phoneme : int
      Number of hidden states to use per phoneme.
  output_folder : str
      It is the folder that the alignments will be stored in when
      saved to disk. Not yet implemented.
  neg_inf : float
      The float used to represent a negative infinite log probability.
      Using `-float("Inf")` tends to give numerical instability.
      A number more negative than -1e5 also sometimes gave errors when
      the `genbmm` library was used (currently not in use). (default: -1e5)
  batch_reduction : string
      One of "none", "sum" or "mean".
      What kind of batch-level reduction to apply to the loss calculated
      in the forward method.
  input_len_norm : bool
      Whether to normalize the loss in the forward method by the length of
      the inputs.
  target_len_norm : bool
      Whether to normalize the loss in the forward method by the length of
      the targets.
  lexicon_path : string
      The location of the lexicon.
  
  Example
  -------
  >>> log_posteriors = torch.tensor([[[ -1., -10., -10.],
  ...                                 [-10.,  -1., -10.],
  ...                                 [-10., -10.,  -1.]],
  ...
  ...                                [[ -1., -10., -10.],
  ...                                 [-10.,  -1., -10.],
  ...                                 [-10., -10., -10.]]])
  >>> lens = torch.tensor([1., 0.66])
  >>> phns = torch.tensor([[0, 1, 2],
  ...                      [0, 1, 0]])
  >>> phn_lens = torch.tensor([1., 0.66])
  >>> aligner = HMMAligner()
  >>> forward_scores = aligner(
  ...        log_posteriors, lens, phns, phn_lens, 'forward'
  ... )
  >>> forward_scores.shape
  torch.Size([2])
  >>> viterbi_scores, alignments = aligner(
  ...        log_posteriors, lens, phns, phn_lens, 'viterbi'
  ... )
  >>> alignments
  [[0, 1, 2], [0, 1]]
  >>> viterbi_scores.shape
  torch.Size([2])
docstr: Calculates the accuracy between predicted alignments and ground truth
  alignments for a single sentence/utterance.
  
  Arguments
  ---------
  alignments_ : list of ints
      The predicted alignments for the utterance.
  ends_ : list of ints
      A list of the sample indices where each ground truth phoneme
      ends, according to the transcription.
  phns_ : list of ints
      The unpadded list of ground truth phonemes in the utterance.
  
  Returns
  -------
  mean_acc : float
      The mean percentage of times that the upsampled predicted alignment
      matches the ground truth alignment.
docstr_tok: ["Calculates","the","accuracy","between","predicted","alignments","and","ground","truth","alignments","for","a","single","sentence\/utterance",".","Arguments","--","--","--","--","-","alignments_",":","list","of","ints","The","predicted","alignments","for","the","utterance",".","ends_",":","list","of","ints","A","list","of","the","sample","indices","where","each","ground","truth","phoneme","ends",",","according","to","the","transcription",".","phns_",":","list","of","ints","The","unpadded","list","of","ground","truth","phonemes","in","the","utterance",".","Returns","--","--","--","-","mean_acc",":","float","The","mean","percentage","of","times","that","the","upsampled","predicted","alignment","matches","the","ground","truth","alignment","."]
code: def _calc_accuracy_sent(self, alignments_, ends_, phns_):
      """Calculates the accuracy between predicted alignments and ground truth
      alignments for a single sentence/utterance.
  
      Arguments
      ---------
      alignments_ : list of ints
          The predicted alignments for the utterance.
      ends_ : list of ints
          A list of the sample indices where each ground truth phoneme
          ends, according to the transcription.
      phns_ : list of ints
          The unpadded list of ground truth phonemes in the utterance.
  
      Returns
      -------
      mean_acc : float
          The mean percentage of times that the upsampled predicted alignment
          matches the ground truth alignment.
      """
      # Create array containing the true alignment at each sample
      ends_ = [0] + [int(end) for end in ends_]
      true_durations = [
          ends_[i] - ends_[i - 1] for i in range(1, len(ends_))
      ]
      true_alignments = []
  
      for i in range(len(phns_)):
          true_alignments += [phns_[i]] * (true_durations[i])
      true_alignments = torch.tensor(true_alignments)
  
      # Upsample the predicted alignment array
      # and make sure length matches that of `true_alignment`
      upsample_factor = int(
          torch.round(
              torch.tensor(len(true_alignments) / len(alignments_))
          )
      )
  
      alignments_ = torch.tensor(alignments_)
      alignments_upsampled = alignments_.repeat_interleave(
          upsample_factor
      )
      alignments_upsampled = alignments_upsampled[
          : len(true_alignments)
      ]
  
      if len(true_alignments) > len(alignments_upsampled):
          alignments_upsampled = torch.nn.functional.pad(
              alignments_upsampled,
              (0, len(true_alignments) - len(alignments_upsampled)),
          )
  
      # Measure sample-wise accuracy
      accuracy = (
          alignments_upsampled == true_alignments
      ).float().mean().item() * 100
  
      return accuracy
  
imports: import torch
  import random
  from speechbrain.utils.checkpoints import register_checkpoint_hooks
  from speechbrain.utils.checkpoints import mark_as_saver
  from speechbrain.utils.checkpoints import mark_as_loader
  from speechbrain.utils.data_utils import undo_padding
label_desc: Use image node_id 16 for calling the HMMAligner obj's underlying member method code with example usage: obj._calc_accuracy_sent(alignments_, ends_, phns_) and returns: accuracy