class_docstr: Dynamic CRF layer is used to approximate the traditional
  Conditional Random Fields (CRF)
  $P(y | x) = 1/Z(x) exp(sum_i s(y_i, x) + sum_i t(y_{i-1}, y_i, x))$
  
  where in this function, we assume the emition scores (s) are given,
  and the transition score is a |V| x |V| matrix $M$
  
  in the following two aspects:
   (1) it used a low-rank approximation for the transition matrix:
       $M = E_1 E_2^T$
   (2) it used a beam to estimate the normalizing factor Z(x)
class_docstr_tok: ["Dynamic","CRF","layer","is","used","to","approximate","the","traditional","Conditional","Random","Fields","(","CRF",")","$","P","(","y","|","x",")","=","1\/Z","(","x",")","exp","(","sum_i","s","(","y_i",",","x",")","+","sum_i","t","(","y_","{","i-1","}",",","y_i",",","x",")",")","$","where","in","this","function",",","we","assume","the","emition","scores","(","s",")","are","given",",","and","the","transition","score","is","a","|V|","x","|V|","matrix","$","M","$","in","the","following","two","aspects",":","(","1",")","it","used","a","low-rank","approximation","for","the","transition","matrix",":","$","M","=","E_1","E_2^T","$","(","2",")","it","used","a","beam","to","estimate","the","normalizing","factor","Z","(","x",")"]
code: def _compute_normalizer(
      self, emissions, targets=None, masks=None, beam=None
  ):
      # HACK: we include "target" which is a hueristic for training
      # HACK: we use a beam of tokens to approximate the normalizing factor (which is bad?)
  
      beam = beam if beam is not None else self.beam
      batch_size, seq_len = emissions.size()[:2]
      if targets is not None:
          _emissions = emissions.scatter(
              2, targets[:, :, None], np.float("inf")
          )
          beam_targets = _emissions.topk(beam, 2)[1]
          beam_emission_scores = emissions.gather(2, beam_targets)
      else:
          beam_emission_scores, beam_targets = emissions.topk(beam, 2)
      beam_transition_score1 = self.E1(
          beam_targets[:, :-1]
      )  # B x (T-1) x K x D
      beam_transition_score2 = self.E2(
          beam_targets[:, 1:]
      )  # B x (T-1) x K x D
      beam_transition_matrix = torch.bmm(
          beam_transition_score1.view(-1, beam, self.rank),
          beam_transition_score2.view(-1, beam, self.rank).transpose(
              1, 2
          ),
      )
      beam_transition_matrix = beam_transition_matrix.view(
          batch_size, -1, beam, beam
      )
  
      # compute the normalizer in the log-space
      score = beam_emission_scores[:, 0]  # B x K
      for i in range(1, seq_len):
          next_score = (
              score[:, :, None] + beam_transition_matrix[:, i - 1]
          )
          next_score = (
              logsumexp(next_score, dim=1) + beam_emission_scores[:, i]
          )
  
          if masks is not None:
              score = torch.where(
                  masks[:, i : i + 1], next_score, score
              )
          else:
              score = next_score
  
      # Sum (log-sum-exp) over all possible tags
      return logsumexp(score, dim=1)
  
file_path: fairseq/fairseq/modules/dynamic_crf_layer.py
imports: import numpy
  import torch
  import torch.nn
label_desc: Use image node_id 6 for calling the DynamicCRF obj's underlying member method code with example usage: obj._compute_normalizer(emissions, targets, masks, beam) and returns: logsumexp