class_docstr: Head of `VarifocalNet (VFNet): An IoU-aware Dense Object
  Detector.<https://arxiv.org/abs/2008.13367>`_.
  
  The VFNet predicts IoU-aware classification scores which mix the
  object presence confidence and object localization accuracy as the
  detection score. It is built on the FCOS architecture and uses ATSS
  for defining positive/negative training examples. The VFNet is trained
  with Varifocal Loss and empolys star-shaped deformable convolution to
  extract features for a bbox.
  
  Args:
      num_classes (int): Number of categories excluding the background
          category.
      in_channels (int): Number of channels in the input feature map.
      regress_ranges (tuple[tuple[int, int]]): Regress range of multiple
          level points.
      center_sampling (bool): If true, use center sampling. Default: False.
      center_sample_radius (float): Radius of center sampling. Default: 1.5.
      sync_num_pos (bool): If true, synchronize the number of positive
          examples across GPUs. Default: True
      gradient_mul (float): The multiplier to gradients from bbox refinement
          and recognition. Default: 0.1.
      bbox_norm_type (str): The bbox normalization type, 'reg_denom' or
          'stride'. Default: reg_denom
      loss_cls_fl (dict): Config of focal loss.
      use_vfl (bool): If true, use varifocal loss for training.
          Default: True.
      loss_cls (dict): Config of varifocal loss.
      loss_bbox (dict): Config of localization loss, GIoU Loss.
      loss_bbox (dict): Config of localization refinement loss, GIoU Loss.
      norm_cfg (dict): dictionary to construct and config norm layer.
          Default: norm_cfg=dict(type='GN', num_groups=32,
          requires_grad=True).
      use_atss (bool): If true, use ATSS to define positive/negative
          examples. Default: True.
      anchor_generator (dict): Config of anchor generator for ATSS.
  
  Example:
      >>> self = VFNetHead(11, 7)
      >>> feats = [torch.rand(1, 7, s, s) for s in [4, 8, 16, 32, 64]]
      >>> cls_score, bbox_pred, bbox_pred_refine= self.forward(feats)
      >>> assert len(cls_score) == len(self.scales)
docstr: Compute loss of the head.
  
  Args:
      cls_scores (list[Tensor]): Box iou-aware scores for each scale
          level, each is a 4D-tensor, the channel number is
          num_points * num_classes.
      bbox_preds (list[Tensor]): Box offsets for each
          scale level, each is a 4D-tensor, the channel number is
          num_points * 4.
      bbox_preds_refine (list[Tensor]): Refined Box offsets for
          each scale level, each is a 4D-tensor, the channel
          number is num_points * 4.
      gt_bboxes (list[Tensor]): Ground truth bboxes for each image with
          shape (num_gts, 4) in [tl_x, tl_y, br_x, br_y] format.
      gt_labels (list[Tensor]): class indices corresponding to each box
      img_metas (list[dict]): Meta information of each image, e.g.,
          image size, scaling factor, etc.
      gt_bboxes_ignore (None | list[Tensor]): specify which bounding
          boxes can be ignored when computing the loss.
          Default: None.
  
  Returns:
      dict[str, Tensor]: A dictionary of loss components.
docstr_tok: ["Compute","loss","of","the","head",".","Args",":","cls_scores","(","list","[","Tensor","]",")",":","Box","iou-aware","scores","for","each","scale","level",",","each","is","a","4D-tensor",",","the","channel","number","is","num_points","*","num_classes",".","bbox_preds","(","list","[","Tensor","]",")",":","Box","offsets","for","each","scale","level",",","each","is","a","4D-tensor",",","the","channel","number","is","num_points","*","4.","bbox_preds_refine","(","list","[","Tensor","]",")",":","Refined","Box","offsets","for","each","scale","level",",","each","is","a","4D-tensor",",","the","channel","number","is","num_points","*","4.","gt_bboxes","(","list","[","Tensor","]",")",":","Ground","truth","bboxes","for","each","image","with","shape","(","num_gts",",","4",")","in","[","tl_x",",","tl_y",",","br_x",",","br_y","]","format",".","gt_labels","(","list","[","Tensor","]",")",":","class","indices","corresponding","to","each","box","img_metas","(","list","[","dict","]",")",":","Meta","information","of","each","image",",","e.g.",",","image","size",",","scaling","factor",",","etc",".","gt_bboxes_ignore","(","None","|","list","[","Tensor","]",")",":","specify","which","bounding","boxes","can","be","ignored","when","computing","the","loss",".","Default",":","None",".","Returns",":","dict","[","str",",","Tensor","]",":","A","dictionary","of","loss","components","."]
code: def loss(
      self,
      cls_scores,
      bbox_preds,
      bbox_preds_refine,
      gt_bboxes,
      gt_labels,
      img_metas,
      gt_bboxes_ignore=None,
  ):
      """Compute loss of the head.
  
      Args:
          cls_scores (list[Tensor]): Box iou-aware scores for each scale
              level, each is a 4D-tensor, the channel number is
              num_points * num_classes.
          bbox_preds (list[Tensor]): Box offsets for each
              scale level, each is a 4D-tensor, the channel number is
              num_points * 4.
          bbox_preds_refine (list[Tensor]): Refined Box offsets for
              each scale level, each is a 4D-tensor, the channel
              number is num_points * 4.
          gt_bboxes (list[Tensor]): Ground truth bboxes for each image with
              shape (num_gts, 4) in [tl_x, tl_y, br_x, br_y] format.
          gt_labels (list[Tensor]): class indices corresponding to each box
          img_metas (list[dict]): Meta information of each image, e.g.,
              image size, scaling factor, etc.
          gt_bboxes_ignore (None | list[Tensor]): specify which bounding
              boxes can be ignored when computing the loss.
              Default: None.
  
      Returns:
          dict[str, Tensor]: A dictionary of loss components.
      """
      assert (
          len(cls_scores) == len(bbox_preds) == len(bbox_preds_refine)
      )
      featmap_sizes = [featmap.size()[-2:] for featmap in cls_scores]
      all_level_points = self.get_points(
          featmap_sizes, bbox_preds[0].dtype, bbox_preds[0].device
      )
      (
          labels,
          label_weights,
          bbox_targets,
          bbox_weights,
      ) = self.get_targets(
          cls_scores,
          all_level_points,
          gt_bboxes,
          gt_labels,
          img_metas,
          gt_bboxes_ignore,
      )
  
      num_imgs = cls_scores[0].size(0)
      # flatten cls_scores, bbox_preds and bbox_preds_refine
      flatten_cls_scores = [
          cls_score.permute(0, 2, 3, 1)
          .reshape(-1, self.cls_out_channels)
          .contiguous()
          for cls_score in cls_scores
      ]
      flatten_bbox_preds = [
          bbox_pred.permute(0, 2, 3, 1).reshape(-1, 4).contiguous()
          for bbox_pred in bbox_preds
      ]
      flatten_bbox_preds_refine = [
          bbox_pred_refine.permute(0, 2, 3, 1)
          .reshape(-1, 4)
          .contiguous()
          for bbox_pred_refine in bbox_preds_refine
      ]
      flatten_cls_scores = torch.cat(flatten_cls_scores)
      flatten_bbox_preds = torch.cat(flatten_bbox_preds)
      flatten_bbox_preds_refine = torch.cat(flatten_bbox_preds_refine)
      flatten_labels = torch.cat(labels)
      flatten_bbox_targets = torch.cat(bbox_targets)
      # repeat points to align with bbox_preds
      flatten_points = torch.cat(
          [points.repeat(num_imgs, 1) for points in all_level_points]
      )
  
      # FG cat_id: [0, num_classes - 1], BG cat_id: num_classes
      bg_class_ind = self.num_classes
      pos_inds = torch.where(
          ((flatten_labels >= 0) & (flatten_labels < bg_class_ind)) > 0
      )[0]
      num_pos = len(pos_inds)
  
      pos_bbox_preds = flatten_bbox_preds[pos_inds]
      pos_bbox_preds_refine = flatten_bbox_preds_refine[pos_inds]
      pos_labels = flatten_labels[pos_inds]
  
      # sync num_pos across all gpus
      if self.sync_num_pos:
          num_pos_avg_per_gpu = reduce_mean(
              pos_inds.new_tensor(num_pos).float()
          ).item()
          num_pos_avg_per_gpu = max(num_pos_avg_per_gpu, 1.0)
      else:
          num_pos_avg_per_gpu = num_pos
  
      if num_pos > 0:
          pos_bbox_targets = flatten_bbox_targets[pos_inds]
          pos_points = flatten_points[pos_inds]
  
          pos_decoded_bbox_preds = distance2bbox(
              pos_points, pos_bbox_preds
          )
          pos_decoded_target_preds = distance2bbox(
              pos_points, pos_bbox_targets
          )
          iou_targets_ini = bbox_overlaps(
              pos_decoded_bbox_preds,
              pos_decoded_target_preds.detach(),
              is_aligned=True,
          ).clamp(min=1e-6)
          bbox_weights_ini = iou_targets_ini.clone().detach()
          iou_targets_ini_avg_per_gpu = reduce_mean(
              bbox_weights_ini.sum()
          ).item()
          bbox_avg_factor_ini = max(iou_targets_ini_avg_per_gpu, 1.0)
          loss_bbox = self.loss_bbox(
              pos_decoded_bbox_preds,
              pos_decoded_target_preds.detach(),
              weight=bbox_weights_ini,
              avg_factor=bbox_avg_factor_ini,
          )
  
          pos_decoded_bbox_preds_refine = distance2bbox(
              pos_points, pos_bbox_preds_refine
          )
          iou_targets_rf = bbox_overlaps(
              pos_decoded_bbox_preds_refine,
              pos_decoded_target_preds.detach(),
              is_aligned=True,
          ).clamp(min=1e-6)
          bbox_weights_rf = iou_targets_rf.clone().detach()
          iou_targets_rf_avg_per_gpu = reduce_mean(
              bbox_weights_rf.sum()
          ).item()
          bbox_avg_factor_rf = max(iou_targets_rf_avg_per_gpu, 1.0)
          loss_bbox_refine = self.loss_bbox_refine(
              pos_decoded_bbox_preds_refine,
              pos_decoded_target_preds.detach(),
              weight=bbox_weights_rf,
              avg_factor=bbox_avg_factor_rf,
          )
  
          # build IoU-aware cls_score targets
          if self.use_vfl:
              pos_ious = iou_targets_rf.clone().detach()
              cls_iou_targets = torch.zeros_like(flatten_cls_scores)
              cls_iou_targets[pos_inds, pos_labels] = pos_ious
      else:
          loss_bbox = pos_bbox_preds.sum() * 0
          loss_bbox_refine = pos_bbox_preds_refine.sum() * 0
          if self.use_vfl:
              cls_iou_targets = torch.zeros_like(flatten_cls_scores)
  
      if self.use_vfl:
          loss_cls = self.loss_cls(
              flatten_cls_scores,
              cls_iou_targets,
              avg_factor=num_pos_avg_per_gpu,
          )
      else:
          loss_cls = self.loss_cls(
              flatten_cls_scores,
              flatten_labels,
              weight=label_weights,
              avg_factor=num_pos_avg_per_gpu,
          )
  
      return dict(
          loss_cls=loss_cls,
          loss_bbox=loss_bbox,
          loss_bbox_rf=loss_bbox_refine,
      )
  
imports: import numpy
  import torch
  import torch.nn
  from mmcv.cnn import ConvModule, Scale, bias_init_with_prob, normal_init
  from mmcv.ops import DeformConv2d
  from mmcv.runner import force_fp32
  from mmdet.core import bbox2distance, bbox_overlaps, build_anchor_generator, build_assigner, build_sampler, distance2bbox, multi_apply, multiclass_nms, reduce_mean
  from ..builder import HEADS, build_loss
  from .atss_head import ATSSHead
  from .fcos_head import FCOSHead
label_desc: Use image node_id 7 for calling the VFNetHead obj's underlying member method code with example usage: obj.loss(cls_scores, bbox_preds, bbox_preds_refine, gt_bboxes, gt_labels, img_metas, gt_bboxes_ignore) and returns: dict