class_docstr: Head of CornerNet: Detecting Objects as Paired Keypoints.
  
  Code is modified from the `official github repo
  <https://github.com/princeton-vl/CornerNet/blob/master/models/py_utils/
  kp.py#L73>`_ .
  
  More details can be found in the `paper
  <https://arxiv.org/abs/1808.01244>`_ .
  
  Args:
      num_classes (int): Number of categories excluding the background
          category.
      in_channels (int): Number of channels in the input feature map.
      num_feat_levels (int): Levels of feature from the previous module. 2
          for HourglassNet-104 and 1 for HourglassNet-52. Because
          HourglassNet-104 outputs the final feature and intermediate
          supervision feature and HourglassNet-52 only outputs the final
          feature. Default: 2.
      corner_emb_channels (int): Channel of embedding vector. Default: 1.
      train_cfg (dict | None): Training config. Useless in CornerHead,
          but we keep this variable for SingleStageDetector. Default: None.
      test_cfg (dict | None): Testing config of CornerHead. Default: None.
      loss_heatmap (dict | None): Config of corner heatmap loss. Default:
          GaussianFocalLoss.
      loss_embedding (dict | None): Config of corner embedding loss. Default:
          AssociativeEmbeddingLoss.
      loss_offset (dict | None): Config of corner offset loss. Default:
          SmoothL1Loss.
class_docstr_tok: ["Head","of","CornerNet",":","Detecting","Objects","as","Paired","Keypoints",".","Code","is","modified","from","the","`","official","github","repo","<","https",":","\/\/github.com\/princeton-vl\/CornerNet\/blob\/master\/models\/py_utils\/","kp.py","#","L73",">","`","_",".","More","details","can","be","found","in","the","`","paper","<","https",":","\/\/arxiv.org\/abs\/1808.01244",">","`","_",".","Args",":","num_classes","(","int",")",":","Number","of","categories","excluding","the","background","category",".","in_channels","(","int",")",":","Number","of","channels","in","the","input","feature","map",".","num_feat_levels","(","int",")",":","Levels","of","feature","from","the","previous","module",".","2","for","HourglassNet-104","and","1","for","HourglassNet-52",".","Because","HourglassNet-104","outputs","the","final","feature","and","intermediate","supervision","feature","and","HourglassNet-52","only","outputs","the","final","feature",".","Default",":","2.","corner_emb_channels","(","int",")",":","Channel","of","embedding","vector",".","Default",":","1.","train_cfg","(","dict","|","None",")",":","Training","config",".","Useless","in","CornerHead",",","but","we","keep","this","variable","for","SingleStageDetector",".","Default",":","None",".","test_cfg","(","dict","|","None",")",":","Testing","config","of","CornerHead",".","Default",":","None",".","loss_heatmap","(","dict","|","None",")",":","Config","of","corner","heatmap","loss",".","Default",":","GaussianFocalLoss",".","loss_embedding","(","dict","|","None",")",":","Config","of","corner","embedding","loss",".","Default",":","AssociativeEmbeddingLoss",".","loss_offset","(","dict","|","None",")",":","Config","of","corner","offset","loss",".","Default",":","SmoothL1Loss","."]
docstr: Transform outputs for a single batch item into raw bbox predictions.
  
  Args:
      tl_heat (Tensor): Top-left corner heatmap for current level with
          shape (N, num_classes, H, W).
      br_heat (Tensor): Bottom-right corner heatmap for current level
          with shape (N, num_classes, H, W).
      tl_off (Tensor): Top-left corner offset for current level with
          shape (N, corner_offset_channels, H, W).
      br_off (Tensor): Bottom-right corner offset for current level with
          shape (N, corner_offset_channels, H, W).
      tl_emb (Tensor | None): Top-left corner embedding for current
          level with shape (N, corner_emb_channels, H, W).
      br_emb (Tensor | None): Bottom-right corner embedding for current
          level with shape (N, corner_emb_channels, H, W).
      tl_centripetal_shift (Tensor | None): Top-left centripetal shift
          for current level with shape (N, 2, H, W).
      br_centripetal_shift (Tensor | None): Bottom-right centripetal
          shift for current level with shape (N, 2, H, W).
      img_meta (dict): Meta information of current image, e.g.,
          image size, scaling factor, etc.
      k (int): Get top k corner keypoints from heatmap.
      kernel (int): Max pooling kernel for extract local maximum pixels.
      distance_threshold (float): Distance threshold. Top-left and
          bottom-right corner keypoints with feature distance less than
          the threshold will be regarded as keypoints from same object.
      num_dets (int): Num of raw boxes before doing nms.
  
  Returns:
      tuple[torch.Tensor]: Decoded output of CornerHead, containing the
      following Tensors:
  
      - bboxes (Tensor): Coords of each box.
      - scores (Tensor): Scores of each box.
      - clses (Tensor): Categories of each box.
docstr_tok: ["Transform","outputs","for","a","single","batch","item","into","raw","bbox","predictions",".","Args",":","tl_heat","(","Tensor",")",":","Top-left","corner","heatmap","for","current","level","with","shape","(","N",",","num_classes",",","H",",","W",")",".","br_heat","(","Tensor",")",":","Bottom-right","corner","heatmap","for","current","level","with","shape","(","N",",","num_classes",",","H",",","W",")",".","tl_off","(","Tensor",")",":","Top-left","corner","offset","for","current","level","with","shape","(","N",",","corner_offset_channels",",","H",",","W",")",".","br_off","(","Tensor",")",":","Bottom-right","corner","offset","for","current","level","with","shape","(","N",",","corner_offset_channels",",","H",",","W",")",".","tl_emb","(","Tensor","|","None",")",":","Top-left","corner","embedding","for","current","level","with","shape","(","N",",","corner_emb_channels",",","H",",","W",")",".","br_emb","(","Tensor","|","None",")",":","Bottom-right","corner","embedding","for","current","level","with","shape","(","N",",","corner_emb_channels",",","H",",","W",")",".","tl_centripetal_shift","(","Tensor","|","None",")",":","Top-left","centripetal","shift","for","current","level","with","shape","(","N",",","2",",","H",",","W",")",".","br_centripetal_shift","(","Tensor","|","None",")",":","Bottom-right","centripetal","shift","for","current","level","with","shape","(","N",",","2",",","H",",","W",")",".","img_meta","(","dict",")",":","Meta","information","of","current","image",",","e.g.",",","image","size",",","scaling","factor",",","etc",".","k","(","int",")",":","Get","top","k","corner","keypoints","from","heatmap",".","kernel","(","int",")",":","Max","pooling","kernel","for","extract","local","maximum","pixels",".","distance_threshold","(","float",")",":","Distance","threshold",".","Top-left","and","bottom-right","corner","keypoints","with","feature","distance","less","than","the","threshold","will","be","regarded","as","keypoints","from","same","object",".","num_dets","(","int",")",":","Num","of","raw","boxes","before","doing","nms",".","Returns",":","tuple","[","torch.Tensor","]",":","Decoded","output","of","CornerHead",",","containing","the","following","Tensors",":","-","bboxes","(","Tensor",")",":","Coords","of","each","box",".","-","scores","(","Tensor",")",":","Scores","of","each","box",".","-","clses","(","Tensor",")",":","Categories","of","each","box","."]
code: def decode_heatmap(
      self,
      tl_heat,
      br_heat,
      tl_off,
      br_off,
      tl_emb=None,
      br_emb=None,
      tl_centripetal_shift=None,
      br_centripetal_shift=None,
      img_meta=None,
      k=100,
      kernel=3,
      distance_threshold=0.5,
      num_dets=1000,
  ):
      """Transform outputs for a single batch item into raw bbox predictions.
  
      Args:
          tl_heat (Tensor): Top-left corner heatmap for current level with
              shape (N, num_classes, H, W).
          br_heat (Tensor): Bottom-right corner heatmap for current level
              with shape (N, num_classes, H, W).
          tl_off (Tensor): Top-left corner offset for current level with
              shape (N, corner_offset_channels, H, W).
          br_off (Tensor): Bottom-right corner offset for current level with
              shape (N, corner_offset_channels, H, W).
          tl_emb (Tensor | None): Top-left corner embedding for current
              level with shape (N, corner_emb_channels, H, W).
          br_emb (Tensor | None): Bottom-right corner embedding for current
              level with shape (N, corner_emb_channels, H, W).
          tl_centripetal_shift (Tensor | None): Top-left centripetal shift
              for current level with shape (N, 2, H, W).
          br_centripetal_shift (Tensor | None): Bottom-right centripetal
              shift for current level with shape (N, 2, H, W).
          img_meta (dict): Meta information of current image, e.g.,
              image size, scaling factor, etc.
          k (int): Get top k corner keypoints from heatmap.
          kernel (int): Max pooling kernel for extract local maximum pixels.
          distance_threshold (float): Distance threshold. Top-left and
              bottom-right corner keypoints with feature distance less than
              the threshold will be regarded as keypoints from same object.
          num_dets (int): Num of raw boxes before doing nms.
  
      Returns:
          tuple[torch.Tensor]: Decoded output of CornerHead, containing the
          following Tensors:
  
          - bboxes (Tensor): Coords of each box.
          - scores (Tensor): Scores of each box.
          - clses (Tensor): Categories of each box.
      """
      with_embedding = tl_emb is not None and br_emb is not None
      with_centripetal_shift = (
          tl_centripetal_shift is not None
          and br_centripetal_shift is not None
      )
      assert with_embedding + with_centripetal_shift == 1
      batch, _, height, width = tl_heat.size()
      inp_h, inp_w, _ = img_meta["pad_shape"]
  
      # perform nms on heatmaps
      tl_heat = self._local_maximum(tl_heat, kernel=kernel)
      br_heat = self._local_maximum(br_heat, kernel=kernel)
  
      tl_scores, tl_inds, tl_clses, tl_ys, tl_xs = self._topk(
          tl_heat, k=k
      )
      br_scores, br_inds, br_clses, br_ys, br_xs = self._topk(
          br_heat, k=k
      )
  
      # We use repeat instead of expand here because expand is a
      # shallow-copy function. Thus it could cause unexpected testing result
      # sometimes. Using expand will decrease about 10% mAP during testing
      # compared to repeat.
      tl_ys = tl_ys.view(batch, k, 1).repeat(1, 1, k)
      tl_xs = tl_xs.view(batch, k, 1).repeat(1, 1, k)
      br_ys = br_ys.view(batch, 1, k).repeat(1, k, 1)
      br_xs = br_xs.view(batch, 1, k).repeat(1, k, 1)
  
      tl_off = self._transpose_and_gather_feat(tl_off, tl_inds)
      tl_off = tl_off.view(batch, k, 1, 2)
      br_off = self._transpose_and_gather_feat(br_off, br_inds)
      br_off = br_off.view(batch, 1, k, 2)
  
      tl_xs = tl_xs + tl_off[..., 0]
      tl_ys = tl_ys + tl_off[..., 1]
      br_xs = br_xs + br_off[..., 0]
      br_ys = br_ys + br_off[..., 1]
  
      if with_centripetal_shift:
          tl_centripetal_shift = (
              self._transpose_and_gather_feat(
                  tl_centripetal_shift, tl_inds
              )
              .view(batch, k, 1, 2)
              .exp()
          )
          br_centripetal_shift = (
              self._transpose_and_gather_feat(
                  br_centripetal_shift, br_inds
              )
              .view(batch, 1, k, 2)
              .exp()
          )
  
          tl_ctxs = tl_xs + tl_centripetal_shift[..., 0]
          tl_ctys = tl_ys + tl_centripetal_shift[..., 1]
          br_ctxs = br_xs - br_centripetal_shift[..., 0]
          br_ctys = br_ys - br_centripetal_shift[..., 1]
  
      # all possible boxes based on top k corners (ignoring class)
      tl_xs *= inp_w / width
      tl_ys *= inp_h / height
      br_xs *= inp_w / width
      br_ys *= inp_h / height
  
      if with_centripetal_shift:
          tl_ctxs *= inp_w / width
          tl_ctys *= inp_h / height
          br_ctxs *= inp_w / width
          br_ctys *= inp_h / height
  
      x_off = img_meta["border"][2]
      y_off = img_meta["border"][0]
  
      tl_xs -= x_off
      tl_ys -= y_off
      br_xs -= x_off
      br_ys -= y_off
  
      tl_xs *= tl_xs.gt(0.0).type_as(tl_xs)
      tl_ys *= tl_ys.gt(0.0).type_as(tl_ys)
      br_xs *= br_xs.gt(0.0).type_as(br_xs)
      br_ys *= br_ys.gt(0.0).type_as(br_ys)
  
      bboxes = torch.stack((tl_xs, tl_ys, br_xs, br_ys), dim=3)
      area_bboxes = ((br_xs - tl_xs) * (br_ys - tl_ys)).abs()
  
      if with_centripetal_shift:
          tl_ctxs -= x_off
          tl_ctys -= y_off
          br_ctxs -= x_off
          br_ctys -= y_off
  
          tl_ctxs *= tl_ctxs.gt(0.0).type_as(tl_ctxs)
          tl_ctys *= tl_ctys.gt(0.0).type_as(tl_ctys)
          br_ctxs *= br_ctxs.gt(0.0).type_as(br_ctxs)
          br_ctys *= br_ctys.gt(0.0).type_as(br_ctys)
  
          ct_bboxes = torch.stack(
              (tl_ctxs, tl_ctys, br_ctxs, br_ctys), dim=3
          )
          area_ct_bboxes = (
              (br_ctxs - tl_ctxs) * (br_ctys - tl_ctys)
          ).abs()
  
          rcentral = torch.zeros_like(ct_bboxes)
          # magic nums from paper section 4.1
          mu = torch.ones_like(area_bboxes) / 2.4
          mu[area_bboxes > 3500] = 1 / 2.1  # large bbox have smaller mu
  
          bboxes_center_x = (bboxes[..., 0] + bboxes[..., 2]) / 2
          bboxes_center_y = (bboxes[..., 1] + bboxes[..., 3]) / 2
          rcentral[..., 0] = (
              bboxes_center_x
              - mu * (bboxes[..., 2] - bboxes[..., 0]) / 2
          )
          rcentral[..., 1] = (
              bboxes_center_y
              - mu * (bboxes[..., 3] - bboxes[..., 1]) / 2
          )
          rcentral[..., 2] = (
              bboxes_center_x
              + mu * (bboxes[..., 2] - bboxes[..., 0]) / 2
          )
          rcentral[..., 3] = (
              bboxes_center_y
              + mu * (bboxes[..., 3] - bboxes[..., 1]) / 2
          )
          area_rcentral = (
              (rcentral[..., 2] - rcentral[..., 0])
              * (rcentral[..., 3] - rcentral[..., 1])
          ).abs()
          dists = area_ct_bboxes / area_rcentral
  
          tl_ctx_inds = (ct_bboxes[..., 0] <= rcentral[..., 0]) | (
              ct_bboxes[..., 0] >= rcentral[..., 2]
          )
          tl_cty_inds = (ct_bboxes[..., 1] <= rcentral[..., 1]) | (
              ct_bboxes[..., 1] >= rcentral[..., 3]
          )
          br_ctx_inds = (ct_bboxes[..., 2] <= rcentral[..., 0]) | (
              ct_bboxes[..., 2] >= rcentral[..., 2]
          )
          br_cty_inds = (ct_bboxes[..., 3] <= rcentral[..., 1]) | (
              ct_bboxes[..., 3] >= rcentral[..., 3]
          )
  
      if with_embedding:
          tl_emb = self._transpose_and_gather_feat(tl_emb, tl_inds)
          tl_emb = tl_emb.view(batch, k, 1)
          br_emb = self._transpose_and_gather_feat(br_emb, br_inds)
          br_emb = br_emb.view(batch, 1, k)
          dists = torch.abs(tl_emb - br_emb)
  
      tl_scores = tl_scores.view(batch, k, 1).repeat(1, 1, k)
      br_scores = br_scores.view(batch, 1, k).repeat(1, k, 1)
  
      scores = (
          tl_scores + br_scores
      ) / 2  # scores for all possible boxes
  
      # tl and br should have same class
      tl_clses = tl_clses.view(batch, k, 1).repeat(1, 1, k)
      br_clses = br_clses.view(batch, 1, k).repeat(1, k, 1)
      cls_inds = tl_clses != br_clses
  
      # reject boxes based on distances
      dist_inds = dists > distance_threshold
  
      # reject boxes based on widths and heights
      width_inds = br_xs <= tl_xs
      height_inds = br_ys <= tl_ys
  
      scores[cls_inds] = -1
      scores[width_inds] = -1
      scores[height_inds] = -1
      scores[dist_inds] = -1
      if with_centripetal_shift:
          scores[tl_ctx_inds] = -1
          scores[tl_cty_inds] = -1
          scores[br_ctx_inds] = -1
          scores[br_cty_inds] = -1
  
      scores = scores.view(batch, -1)
      scores, inds = torch.topk(scores, num_dets)
      scores = scores.unsqueeze(2)
  
      bboxes = bboxes.view(batch, -1, 4)
      bboxes = self._gather_feat(bboxes, inds)
  
      clses = tl_clses.contiguous().view(batch, -1, 1)
      clses = self._gather_feat(clses, inds).float()
  
      return bboxes, scores, clses
  
imports: from math import ceil, log
  import torch
  import torch.nn
  import torch.nn.functional
  from mmcv.cnn import ConvModule, bias_init_with_prob
  from mmcv.ops import CornerPool, batched_nms
  from mmdet.core import multi_apply
  from ..builder import HEADS, build_loss
  from ..utils import gaussian_radius, gen_gaussian_target
  from .base_dense_head import BaseDenseHead
label_desc: Use image node_id 19 for calling the CornerHead obj's underlying member method code with example usage: obj.decode_heatmap(tl_heat, br_heat, tl_off, br_off, tl_emb, br_emb, tl_centripetal_shift, br_centripetal_shift, img_meta, k, kernel, distance_threshold, num_dets) and returns: bboxes,  scores,  clses