class_docstr: Generalized Focal Loss: Learning Qualified and Distributed Bounding
  Boxes for Dense Object Detection.
  
  GFL head structure is similar with ATSS, however GFL uses
  1) joint representation for classification and localization quality, and
  2) flexible General distribution for bounding box locations,
  which are supervised by
  Quality Focal Loss (QFL) and Distribution Focal Loss (DFL), respectively
  
  https://arxiv.org/abs/2006.04388
  
  Args:
      num_classes (int): Number of categories excluding the background
          category.
      in_channels (int): Number of channels in the input feature map.
      stacked_convs (int): Number of conv layers in cls and reg tower.
          Default: 4.
      conv_cfg (dict): dictionary to construct and config conv layer.
          Default: None.
      norm_cfg (dict): dictionary to construct and config norm layer.
          Default: dict(type='GN', num_groups=32, requires_grad=True).
      loss_qfl (dict): Config of Quality Focal Loss (QFL).
      reg_max (int): Max value of integral set :math: `{0, ..., reg_max}`
          in QFL setting. Default: 16.
  Example:
      >>> self = GFLHead(11, 7)
      >>> feats = [torch.rand(1, 7, s, s) for s in [4, 8, 16, 32, 64]]
      >>> cls_quality_score, bbox_pred = self.forward(feats)
      >>> assert len(cls_quality_score) == len(self.scales)
class_docstr_tok: ["Generalized","Focal","Loss",":","Learning","Qualified","and","Distributed","Bounding","Boxes","for","Dense","Object","Detection",".","GFL","head","structure","is","similar","with","ATSS",",","however","GFL","uses","1",")","joint","representation","for","classification","and","localization","quality",",","and","2",")","flexible","General","distribution","for","bounding","box","locations",",","which","are","supervised","by","Quality","Focal","Loss","(","QFL",")","and","Distribution","Focal","Loss","(","DFL",")",",","respectively","https",":","\/\/arxiv.org\/abs\/2006.04388","Args",":","num_classes","(","int",")",":","Number","of","categories","excluding","the","background","category",".","in_channels","(","int",")",":","Number","of","channels","in","the","input","feature","map",".","stacked_convs","(","int",")",":","Number","of","conv","layers","in","cls","and","reg","tower",".","Default",":","4.","conv_cfg","(","dict",")",":","dictionary","to","construct","and","config","conv","layer",".","Default",":","None",".","norm_cfg","(","dict",")",":","dictionary","to","construct","and","config","norm","layer",".","Default",":","dict","(","type='GN","'",",","num_groups=32",",","requires_grad=True",")",".","loss_qfl","(","dict",")",":","Config","of","Quality","Focal","Loss","(","QFL",")",".","reg_max","(","int",")",":","Max","value","of","integral","set",":","math",":","`","{","0",",","...",",","reg_max","}","`","in","QFL","setting",".","Default",":","16",".","Example",":",">",">",">","self","=","GFLHead","(","11",",","7",")",">",">",">","feats","=","[","torch.rand","(","1",",","7",",","s",",","s",")","for","s","in","[","4",",","8",",","16",",","32",",","64","]","]",">",">",">","cls_quality_score",",","bbox_pred","=","self.forward","(","feats",")",">",">",">","assert","len","(","cls_quality_score",")","==","len","(","self.scales",")"]
docstr: Transform network output for a batch into bbox predictions.
  
  Args:
      cls_scores (list[Tensor]): Box scores for each scale level
          Has shape (N, num_anchors * num_classes, H, W)
      bbox_preds (list[Tensor]): Box energies / deltas for each scale
          level with shape (N, num_anchors * 4, H, W)
      img_metas (list[dict]): Meta information of each image, e.g.,
          image size, scaling factor, etc.
      cfg (mmcv.Config | None): Test / postprocessing configuration,
          if None, test_cfg would be used
      rescale (bool): If True, return boxes in original image space.
          Default: False.
      with_nms (bool): If True, do nms before return boxes.
          Default: True.
  
  Returns:
      list[tuple[Tensor, Tensor]]: Each item in result_list is 2-tuple.
          The first item is an (n, 5) tensor, where the first 4 columns
          are bounding box positions (tl_x, tl_y, br_x, br_y) and the
          5-th column is a score between 0 and 1. The second item is a
          (n,) tensor where each item is the predicted class labelof the
          corresponding box.
  
  Example:
      >>> import mmcv
      >>> self = AnchorHead(
      >>>     num_classes=9,
      >>>     in_channels=1,
      >>>     anchor_generator=dict(
      >>>         type='AnchorGenerator',
      >>>         scales=[8],
      >>>         ratios=[0.5, 1.0, 2.0],
      >>>         strides=[4,]))
      >>> img_metas = [{'img_shape': (32, 32, 3), 'scale_factor': 1}]
      >>> cfg = mmcv.Config(dict(
      >>>     score_thr=0.00,
      >>>     nms=dict(type='nms', iou_thr=1.0),
      >>>     max_per_img=10))
      >>> feat = torch.rand(1, 1, 3, 3)
      >>> cls_score, bbox_pred = self.forward_single(feat)
      >>> # note the input lists are over different levels, not images
      >>> cls_scores, bbox_preds = [cls_score], [bbox_pred]
      >>> result_list = self.get_bboxes(cls_scores, bbox_preds,
      >>>                               img_metas, cfg)
      >>> det_bboxes, det_labels = result_list[0]
      >>> assert len(result_list) == 1
      >>> assert det_bboxes.shape[1] == 5
      >>> assert len(det_bboxes) == len(det_labels) == cfg.max_per_img
docstr_tok: ["Transform","network","output","for","a","batch","into","bbox","predictions",".","Args",":","cls_scores","(","list","[","Tensor","]",")",":","Box","scores","for","each","scale","level","Has","shape","(","N",",","num_anchors","*","num_classes",",","H",",","W",")","bbox_preds","(","list","[","Tensor","]",")",":","Box","energies","\/","deltas","for","each","scale","level","with","shape","(","N",",","num_anchors","*","4",",","H",",","W",")","img_metas","(","list","[","dict","]",")",":","Meta","information","of","each","image",",","e.g.",",","image","size",",","scaling","factor",",","etc",".","cfg","(","mmcv.Config","|","None",")",":","Test","\/","postprocessing","configuration",",","if","None",",","test_cfg","would","be","used","rescale","(","bool",")",":","If","True",",","return","boxes","in","original","image","space",".","Default",":","False",".","with_nms","(","bool",")",":","If","True",",","do","nms","before","return","boxes",".","Default",":","True",".","Returns",":","list","[","tuple","[","Tensor",",","Tensor","]","]",":","Each","item","in","result_list","is","2-tuple",".","The","first","item","is","an","(","n",",","5",")","tensor",",","where","the","first","4","columns","are","bounding","box","positions","(","tl_x",",","tl_y",",","br_x",",","br_y",")","and","the","5-th","column","is","a","score","between","0","and","1",".","The","second","item","is","a","(","n",",",")","tensor","where","each","item","is","the","predicted","class","labelof","the","corresponding","box",".","Example",":",">",">",">","import","mmcv",">",">",">","self","=","AnchorHead","(",">",">",">","num_classes=9",",",">",">",">","in_channels=1",",",">",">",">","anchor_generator=dict","(",">",">",">","type='AnchorGenerator","'",",",">",">",">","scales=","[","8","]",",",">",">",">","ratios=","[","0.5",",","1.0",",","2.0","]",",",">",">",">","strides=","[","4",",","]",")",")",">",">",">","img_metas","=","[","{","'img_shape","'",":","(","32",",","32",",","3",")",",","'scale_factor","'",":","1","}","]",">",">",">","cfg","=","mmcv.Config","(","dict","(",">",">",">","score_thr=0.00",",",">",">",">","nms=dict","(","type='nms","'",",","iou_thr=1.0",")",",",">",">",">","max_per_img=10",")",")",">",">",">","feat","=","torch.rand","(","1",",","1",",","3",",","3",")",">",">",">","cls_score",",","bbox_pred","=","self.forward_single","(","feat",")",">",">",">","#","note","the","input","lists","are","over","different","levels",",","not","images",">",">",">","cls_scores",",","bbox_preds","=","[","cls_score","]",",","[","bbox_pred","]",">",">",">","result_list","=","self.get_bboxes","(","cls_scores",",","bbox_preds",",",">",">",">","img_metas",",","cfg",")",">",">",">","det_bboxes",",","det_labels","=","result_list","[","0","]",">",">",">","assert","len","(","result_list",")","==","1",">",">",">","assert","det_bboxes.shape","[","1","]","==","5",">",">",">","assert","len","(","det_bboxes",")","==","len","(","det_labels",")","==","cfg.max_per_img"]
code: def get_bboxes(
      self,
      cls_scores,
      bbox_preds,
      kps_preds,
      img_metas,
      cfg=None,
      rescale=False,
      with_nms=True,
  ):
      """Transform network output for a batch into bbox predictions.
  
      Args:
          cls_scores (list[Tensor]): Box scores for each scale level
              Has shape (N, num_anchors * num_classes, H, W)
          bbox_preds (list[Tensor]): Box energies / deltas for each scale
              level with shape (N, num_anchors * 4, H, W)
          img_metas (list[dict]): Meta information of each image, e.g.,
              image size, scaling factor, etc.
          cfg (mmcv.Config | None): Test / postprocessing configuration,
              if None, test_cfg would be used
          rescale (bool): If True, return boxes in original image space.
              Default: False.
          with_nms (bool): If True, do nms before return boxes.
              Default: True.
  
      Returns:
          list[tuple[Tensor, Tensor]]: Each item in result_list is 2-tuple.
              The first item is an (n, 5) tensor, where the first 4 columns
              are bounding box positions (tl_x, tl_y, br_x, br_y) and the
              5-th column is a score between 0 and 1. The second item is a
              (n,) tensor where each item is the predicted class labelof the
              corresponding box.
  
      Example:
          >>> import mmcv
          >>> self = AnchorHead(
          >>>     num_classes=9,
          >>>     in_channels=1,
          >>>     anchor_generator=dict(
          >>>         type='AnchorGenerator',
          >>>         scales=[8],
          >>>         ratios=[0.5, 1.0, 2.0],
          >>>         strides=[4,]))
          >>> img_metas = [{'img_shape': (32, 32, 3), 'scale_factor': 1}]
          >>> cfg = mmcv.Config(dict(
          >>>     score_thr=0.00,
          >>>     nms=dict(type='nms', iou_thr=1.0),
          >>>     max_per_img=10))
          >>> feat = torch.rand(1, 1, 3, 3)
          >>> cls_score, bbox_pred = self.forward_single(feat)
          >>> # note the input lists are over different levels, not images
          >>> cls_scores, bbox_preds = [cls_score], [bbox_pred]
          >>> result_list = self.get_bboxes(cls_scores, bbox_preds,
          >>>                               img_metas, cfg)
          >>> det_bboxes, det_labels = result_list[0]
          >>> assert len(result_list) == 1
          >>> assert det_bboxes.shape[1] == 5
          >>> assert len(det_bboxes) == len(det_labels) == cfg.max_per_img
      """
      assert len(cls_scores) == len(bbox_preds)
      num_levels = len(cls_scores)
  
      device = cls_scores[0].device
      featmap_sizes = [
          cls_scores[i].shape[-2:] for i in range(num_levels)
      ]
      mlvl_anchors = self.anchor_generator.grid_anchors(
          featmap_sizes, device=device
      )
  
      result_list = []
      for img_id in range(len(img_metas)):
          cls_score_list = [
              cls_scores[i][img_id].detach() for i in range(num_levels)
          ]
          bbox_pred_list = [
              bbox_preds[i][img_id].detach() for i in range(num_levels)
          ]
          img_shape = img_metas[img_id]["img_shape"]
          scale_factor = img_metas[img_id]["scale_factor"]
          if with_nms:
              # some heads don't support with_nms argument
              proposals = self._get_bboxes_single(
                  cls_score_list,
                  bbox_pred_list,
                  mlvl_anchors,
                  img_shape,
                  scale_factor,
                  cfg,
                  rescale,
              )
          else:
              proposals = self._get_bboxes_single(
                  cls_score_list,
                  bbox_pred_list,
                  mlvl_anchors,
                  img_shape,
                  scale_factor,
                  cfg,
                  rescale,
                  with_nms,
              )
          result_list.append(proposals)
      return result_list
  
imports: import numpy
  import torch
  import torch.nn
  import torch.nn.functional
  from mmcv.cnn import ConvModule, Scale, bias_init_with_prob, normal_init, DepthwiseSeparableConvModule
  from mmcv.cnn import constant_init, kaiming_init
  from mmcv.runner import force_fp32
  from mmdet.core import anchor_inside_flags, bbox2distance, bbox_overlaps, build_assigner, build_sampler, distance2bbox, distance2kps, kps2distance, images_to_levels, multi_apply, multiclass_nms, reduce_mean, unmap
  from ..builder import HEADS, build_loss
  from .anchor_head import AnchorHead
  from .base_dense_head import BaseDenseHead
  from .dense_test_mixins import BBoxTestMixin
label_desc: Use image node_id 12 for calling the SCRFDHead obj's underlying member method code with example usage: obj.get_bboxes(cls_scores, bbox_preds, kps_preds, img_metas, cfg, rescale, with_nms) and returns: result_list