class_docstr: Calculates the loss for each sequence up to its length t.
class_docstr_tok: ["Calculates","the","loss","for","each","sequence","up","to","its","length","t","."]
docstr: Forward propagation of Viterbi Loss.
  
  Args:
      features_tuple: CRF scores from forward method in shape (batch size, seq len, tagset size, tagset size), lengths of sentences in batch, transitions from CRF
      targets: true tags for sentences which will be converted to matrix indices.
  
  Returns: summed Viterbi Loss over all data points
docstr_tok: ["Forward","propagation","of","Viterbi","Loss",".","Args",":","features_tuple",":","CRF","scores","from","forward","method","in","shape","(","batch","size",",","seq","len",",","tagset","size",",","tagset","size",")",",","lengths","of","sentences","in","batch",",","transitions","from","CRF","targets",":","true","tags","for","sentences","which","will","be","converted","to","matrix","indices",".","Returns",":","summed","Viterbi","Loss","over","all","data","points"]
code: def forward(
      self, features_tuple: tuple, targets: torch.Tensor
  ) -> torch.Tensor:
      """Forward propagation of Viterbi Loss.
  
      Args:
          features_tuple: CRF scores from forward method in shape (batch size, seq len, tagset size, tagset size), lengths of sentences in batch, transitions from CRF
          targets: true tags for sentences which will be converted to matrix indices.
  
      Returns: summed Viterbi Loss over all data points
      """
      features, lengths, transitions = features_tuple
  
      batch_size = features.size(0)
      seq_len = features.size(1)
  
      targets, targets_matrix_indices = self._format_targets(
          targets, lengths
      )
      targets_matrix_indices = (
          torch.tensor(targets_matrix_indices, dtype=torch.long)
          .unsqueeze(2)
          .to(flair.device)
      )
  
      # scores_at_targets[range(features.shape[0]), lengths.values -1]
      # Squeeze crf scores matrices in 1-dim shape and gather scores at targets by matrix indices
      scores_at_targets = torch.gather(
          features.view(batch_size, seq_len, -1),
          2,
          targets_matrix_indices,
      )
      scores_at_targets = pack_padded_sequence(
          scores_at_targets, lengths, batch_first=True
      )[0]
      transitions_to_stop = transitions[
          np.repeat(self.stop_tag, features.shape[0]),
          [
              target[length - 1]
              for target, length in zip(targets, lengths)
          ],
      ]
      gold_score = scores_at_targets.sum() + transitions_to_stop.sum()
  
      scores_upto_t = torch.zeros(
          batch_size,
          self.tagset_size,
          device=flair.device,
          dtype=features.dtype,
      )
  
      for t in range(max(lengths)):
          batch_size_t = sum(
              [length > t for length in lengths]
          )  # since batch is ordered, we can save computation time by reducing our effective batch_size
  
          if t == 0:
              # Initially, get scores from <start> tag to all other tags
              scores_upto_t[:batch_size_t] = (
                  scores_upto_t[:batch_size_t]
                  + features[:batch_size_t, t, :, self.start_tag]
              )
          else:
              # We add scores at current timestep to scores accumulated up to previous timestep, and log-sum-exp
              # Remember, the cur_tag of the previous timestep is the prev_tag of this timestep
              scores_upto_t[:batch_size_t] = self._log_sum_exp(
                  features[:batch_size_t, t, :, :]
                  + scores_upto_t[:batch_size_t].unsqueeze(1),
                  dim=2,
              )
  
      all_paths_scores = self._log_sum_exp(
          scores_upto_t + transitions[self.stop_tag].unsqueeze(0), dim=1
      ).sum()
  
      viterbi_loss = all_paths_scores - gold_score
  
      return viterbi_loss
  
file_path: flair/flair/models/sequence_tagger_utils/viterbi.py
imports: from typing import Tuple
  import numpy
  import torch
  import torch.nn
  from torch.nn.functional import softmax
  from torch.nn.utils.rnn import pack_padded_sequence
  import flair
  from flair.data import Dictionary, Label, List, Sentence
label_desc: Use image node_id 2 for calling the ViterbiLoss obj's underlying member method code with example usage: obj.forward(features_tuple, targets) and returns: viterbi_loss