class_docstr: Calculate log-space crf loss, given unary potentials, a transition matrix
  and gold tag sequences.
class_docstr_tok: ["Calculate","log-space","crf","loss",",","given","unary","potentials",",","a","transition","matrix","and","gold","tag","sequences","."]
docstr: Calculate the CRF partition in log space for each instance, following:
      http://www.cs.columbia.edu/~mcollins/fb.pdf
  @return:
      log_norm: batch_size
docstr_tok: ["Calculate","the","CRF","partition","in","log","space","for","each","instance",",","following",":","http",":","\/\/www.cs.columbia.edu\/~mcollins\/fb.pdf","@","return",":","log_norm",":","batch_size"]
code: def crf_log_norm(self, inputs, masks, tag_indices):
      """
      Calculate the CRF partition in log space for each instance, following:
          http://www.cs.columbia.edu/~mcollins/fb.pdf
      @return:
          log_norm: batch_size
      """
      start_inputs = inputs[:, 0, :]  # bs x nc
      rest_inputs = inputs[:, 1:, :]
      # TODO: technically we need to pay attention to the initial
      # value being masked.  Currently we do compensate for the
      # entire row being masked at the end of the operation
      rest_masks = masks[:, 1:]
      alphas = start_inputs  # bs x nc
      trans = self._transitions.unsqueeze(0)  # 1 x nc x nc
      # accumulate alphas in log space
      for i in range(rest_inputs.size(1)):
          transition_scores = (
              alphas.unsqueeze(2) + trans
          )  # bs x nc x nc
          new_alphas = rest_inputs[:, i, :] + log_sum_exp(
              transition_scores, dim=1
          )
          m = (
              rest_masks[:, i].unsqueeze(1).expand_as(new_alphas)
          )  # bs x nc, 1 for padding idx
          # apply masks
          new_alphas.masked_scatter_(m, alphas.masked_select(m))
          alphas = new_alphas
      log_norm = log_sum_exp(alphas, dim=1)
  
      # if any row was entirely masked, we just turn its log denominator to 0
      # eg, the empty summation for the denominator will be 1, and its log will be 0
      all_masked = torch.all(masks, dim=1)
      log_norm = log_norm * torch.logical_not(all_masked)
      return log_norm
  
file_path: stanza/stanza/models/common/crf.py
imports: import math
  from numbers import Number
  import numpy
  import torch
  from torch import nn
  import torch.nn.init
label_desc: Use image node_id 5 for calling the CRFLoss obj's underlying member method code with example usage: obj.crf_log_norm(inputs, masks, tag_indices) and returns: log_norm