class_docstr: This module uses the "forward-backward" algorithm to compute
  the log-likelihood of its inputs assuming a conditional random field model.
  
  See, e.g. http://www.cs.columbia.edu/~mcollins/fb.pdf
  
  # Parameters
  
  num_tags : `int`, required
      The number of tags.
  constraints : `List[Tuple[int, int]]`, optional (default = `None`)
      An optional list of allowed transitions (from_tag_id, to_tag_id).
      These are applied to `viterbi_tags()` but do not affect `forward()`.
      These should be derived from `allowed_transitions` so that the
      start and end transitions are handled correctly for your tag type.
  include_start_end_transitions : `bool`, optional (default = `True`)
      Whether to include the start and end transition parameters.
class_docstr_tok: ["This","module","uses","the","``","forward-backward","''","algorithm","to","compute","the","log-likelihood","of","its","inputs","assuming","a","conditional","random","field","model",".","See",",","e.g",".","http",":","\/\/www.cs.columbia.edu\/~mcollins\/fb.pdf","#","Parameters","num_tags",":","`","int","`",",","required","The","number","of","tags",".","constraints",":","`","List","[","Tuple","[","int",",","int","]","]","`",",","optional","(","default","=","`","None","`",")","An","optional","list","of","allowed","transitions","(","from_tag_id",",","to_tag_id",")",".","These","are","applied","to","`","viterbi_tags","(",")","`","but","do","not","affect","`","forward","(",")","`",".","These","should","be","derived","from","`","allowed_transitions","`","so","that","the","start","and","end","transitions","are","handled","correctly","for","your","tag","type",".","include_start_end_transitions",":","`","bool","`",",","optional","(","default","=","`","True","`",")","Whether","to","include","the","start","and","end","transition","parameters","."]
docstr: Uses viterbi algorithm to find most likely tags for the given inputs.
  If constraints are applied, disallows all other transitions.
  
  Returns a list of results, of the same size as the batch (one result per batch member)
  Each result is a List of length top_k, containing the top K viterbi decodings
  Each decoding is a tuple  (tag_sequence, viterbi_score)
  
  For backwards compatibility, if top_k is None, then instead returns a flat list of
  tag sequences (the top tag sequence for each batch item).
docstr_tok: ["Uses","viterbi","algorithm","to","find","most","likely","tags","for","the","given","inputs",".","If","constraints","are","applied",",","disallows","all","other","transitions",".","Returns","a","list","of","results",",","of","the","same","size","as","the","batch","(","one","result","per","batch","member",")","Each","result","is","a","List","of","length","top_k",",","containing","the","top","K","viterbi","decodings","Each","decoding","is","a","tuple","(","tag_sequence",",","viterbi_score",")","For","backwards","compatibility",",","if","top_k","is","None",",","then","instead","returns","a","flat","list","of","tag","sequences","(","the","top","tag","sequence","for","each","batch","item",")","."]
code: def viterbi_tags(
      self,
      logits: torch.Tensor,
      mask: torch.BoolTensor = None,
      top_k: int = None,
  ) -> Union[List[VITERBI_DECODING], List[List[VITERBI_DECODING]]]:
      """
      Uses viterbi algorithm to find most likely tags for the given inputs.
      If constraints are applied, disallows all other transitions.
  
      Returns a list of results, of the same size as the batch (one result per batch member)
      Each result is a List of length top_k, containing the top K viterbi decodings
      Each decoding is a tuple  (tag_sequence, viterbi_score)
  
      For backwards compatibility, if top_k is None, then instead returns a flat list of
      tag sequences (the top tag sequence for each batch item).
      """
      if mask is None:
          mask = torch.ones(
              *logits.shape[:2], dtype=torch.bool, device=logits.device
          )
  
      if top_k is None:
          top_k = 1
          flatten_output = True
      else:
          flatten_output = False
  
      _, max_seq_length, num_tags = logits.size()
  
      # Get the tensors out of the variables
      logits, mask = logits.data, mask.data
  
      # Augment transitions matrix with start and end transitions
      start_tag = num_tags
      end_tag = num_tags + 1
      transitions = torch.full(
          (num_tags + 2, num_tags + 2), -10000.0, device=logits.device
      )
  
      # Apply transition constraints
      constrained_transitions = (
          self.transitions * self._constraint_mask[:num_tags, :num_tags]
          + -10000.0 * (1 - self._constraint_mask[:num_tags, :num_tags])
      )
      transitions[:num_tags, :num_tags] = constrained_transitions.data
  
      if self.include_start_end_transitions:
          transitions[
              start_tag, :num_tags
          ] = self.start_transitions.detach() * self._constraint_mask[
              start_tag, :num_tags
          ].data + -10000.0 * (
              1 - self._constraint_mask[start_tag, :num_tags].detach()
          )
          transitions[
              :num_tags, end_tag
          ] = self.end_transitions.detach() * self._constraint_mask[
              :num_tags, end_tag
          ].data + -10000.0 * (
              1 - self._constraint_mask[:num_tags, end_tag].detach()
          )
      else:
          transitions[start_tag, :num_tags] = -10000.0 * (
              1 - self._constraint_mask[start_tag, :num_tags].detach()
          )
          transitions[:num_tags, end_tag] = -10000.0 * (
              1 - self._constraint_mask[:num_tags, end_tag].detach()
          )
  
      best_paths = []
      # Pad the max sequence length by 2 to account for start_tag + end_tag.
      tag_sequence = torch.empty(
          max_seq_length + 2, num_tags + 2, device=logits.device
      )
  
      for prediction, prediction_mask in zip(logits, mask):
          mask_indices = prediction_mask.nonzero(
              as_tuple=False
          ).squeeze()
          masked_prediction = torch.index_select(
              prediction, 0, mask_indices
          )
          sequence_length = masked_prediction.shape[0]
  
          # Start with everything totally unlikely
          tag_sequence.fill_(-10000.0)
          # At timestep 0 we must have the START_TAG
          tag_sequence[0, start_tag] = 0.0
          # At steps 1, ..., sequence_length we just use the incoming prediction
          tag_sequence[
              1 : (sequence_length + 1), :num_tags
          ] = masked_prediction
          # And at the last timestep we must have the END_TAG
          tag_sequence[sequence_length + 1, end_tag] = 0.0
  
          # We pass the tags and the transitions to `viterbi_decode`.
          viterbi_paths, viterbi_scores = util.viterbi_decode(
              tag_sequence=tag_sequence[: (sequence_length + 2)],
              transition_matrix=transitions,
              top_k=top_k,
          )
          top_k_paths = []
          for viterbi_path, viterbi_score in zip(
              viterbi_paths, viterbi_scores
          ):
              # Get rid of START and END sentinels and append.
              viterbi_path = viterbi_path[1:-1]
              top_k_paths.append((viterbi_path, viterbi_score.item()))
          best_paths.append(top_k_paths)
  
      if flatten_output:
          return [top_k_paths[0] for top_k_paths in best_paths]
  
      return best_paths
  
file_path: allennlp/allennlp/modules/conditional_random_field/conditional_random_field.py
imports: from typing import List, Tuple, Dict, Union
  import torch
  from allennlp.common.checks import ConfigurationError
  import allennlp.nn.util
label_desc: Use image node_id 6 for calling the ConditionalRandomField obj's underlying member method code with example usage: obj.viterbi_tags(logits, mask, top_k) and returns: best_paths, unknown