docstr: Retuns scores for *inclusive* mention boundaries
docstr_tok: ["Retuns","scores","for","*","inclusive","*","mention","boundaries"]
code: def forward(self, bert_output, mask_ctxt):
      """
      Retuns scores for *inclusive* mention boundaries
      """
      # (bs, seqlen, 3)
      logits = self.bound_classifier(bert_output)
      if self.scoring_method[:2] == "qa":
          # (bs, seqlen, 1); (bs, seqlen, 1); (bs, seqlen, 1)
          start_logprobs, end_logprobs, mention_logprobs = logits.split(
              1, dim=-1
          )
          # (bs, seqlen)
          start_logprobs = start_logprobs.squeeze(-1)
          end_logprobs = end_logprobs.squeeze(-1)
          mention_logprobs = mention_logprobs.squeeze(-1)
          # impossible to choose masked tokens as starts/ends of spans
          start_logprobs[~mask_ctxt] = -float("Inf")
          end_logprobs[~mask_ctxt] = -float("Inf")
          mention_logprobs[~mask_ctxt] = -float("Inf")
  
          # take sum of log softmaxes:
          # log p(mention) = log p(start_pos && end_pos) = log p(start_pos) + log p(end_pos)
          # DIM: (bs, starts, ends)
          mention_scores = start_logprobs.unsqueeze(
              2
          ) + end_logprobs.unsqueeze(1)
          # (bs, starts, ends)
          mention_cum_scores = torch.zeros(
              mention_scores.size(), dtype=mention_scores.dtype
          ).to(mention_scores.device)
          # add ends
          mention_logprobs_end_cumsum = torch.zeros(
              mask_ctxt.size(0), dtype=mention_scores.dtype
          ).to(mention_scores.device)
          for i in range(mask_ctxt.size(1)):
              mention_logprobs_end_cumsum += mention_logprobs[:, i]
              mention_cum_scores[
                  :, :, i
              ] += mention_logprobs_end_cumsum.unsqueeze(-1)
          # subtract starts
          mention_logprobs_start_cumsum = torch.zeros(
              mask_ctxt.size(0), dtype=mention_scores.dtype
          ).to(mention_scores.device)
          for i in range(mask_ctxt.size(1) - 1):
              mention_logprobs_start_cumsum += mention_logprobs[:, i]
              mention_cum_scores[
                  :, (i + 1), :
              ] -= mention_logprobs_start_cumsum.unsqueeze(-1)
  
          # DIM: (bs, starts, ends)
          mention_scores += mention_cum_scores
  
          # DIM: (starts, ends, 2) -- tuples of [start_idx, end_idx]
          mention_bounds = torch.stack(
              [
                  torch.arange(mention_scores.size(1))
                  .unsqueeze(-1)
                  .expand(
                      mention_scores.size(1), mention_scores.size(2)
                  ),  # start idxs
                  torch.arange(mention_scores.size(1))
                  .unsqueeze(0)
                  .expand(
                      mention_scores.size(1), mention_scores.size(2)
                  ),  # end idxs
              ],
              dim=-1,
          ).to(mask_ctxt.device)
          # DIM: (starts, ends)
          mention_sizes = (
              mention_bounds[:, :, 1] - mention_bounds[:, :, 0] + 1
          )  # (+1 as ends are inclusive)
  
          # Remove invalids (startpos > endpos, endpos > seqlen) and renormalize
          # DIM: (bs, starts, ends)
          valid_mask = (
              mention_sizes.unsqueeze(0) > 0
          ) & mask_ctxt.unsqueeze(1)
          # DIM: (bs, starts, ends)
          mention_scores[~valid_mask] = -float(
              "inf"
          )  # invalids have logprob=-inf (p=0)
          # DIM: (bs, starts * ends)
          mention_scores = mention_scores.view(
              mention_scores.size(0), -1
          )
          # DIM: (bs, starts * ends, 2)
          mention_bounds = mention_bounds.view(-1, 2)
          mention_bounds = mention_bounds.unsqueeze(0).expand(
              mention_scores.size(0), mention_scores.size(1), 2
          )
  
      if self.max_mention_length is not None:
          mention_scores, mention_bounds = self.filter_by_mention_size(
              mention_scores,
              mention_bounds,
              self.max_mention_length,
          )
  
      return mention_scores, mention_bounds
  
imports: import os
  import numpy
  import torch
  import torch.nn
  import torch.nn.functional
  from tqdm import tqdm
  from collections import OrderedDict
  from pytorch_transformers.modeling_bert import BertPreTrainedModel, BertConfig, BertModel
  from pytorch_transformers.tokenization_bert import BertTokenizer
  from elq.common.ranker_base import BertEncoder, get_model_obj
  from blink.common.optimizer import get_bert_optimizer
  from elq.biencoder.allennlp_span_utils import batched_span_select, batched_index_select
  from elq.biencoder.utils import batch_reshape_mask_left
label_desc: Use image node_id 2 for calling the MentionScoresHead obj's underlying member method code with example usage: obj.forward(bert_output, mask_ctxt) and returns: mention_scores,  mention_bounds