class_docstr: Anchor-free head used in `FSAF <https://arxiv.org/abs/1903.00621>`_.
  
  The head contains two subnetworks. The first classifies anchor boxes and
  the second regresses deltas for the anchors (num_anchors is 1 for anchor-
  free methods)
  
  Args:
      *args: Same as its base class in :class:`RetinaHead`
      score_threshold (float, optional): The score_threshold to calculate
          positive recall. If given, prediction scores lower than this value
          is counted as incorrect prediction. Default to None.
      **kwargs: Same as its base class in :class:`RetinaHead`
  
  Example:
      >>> import torch
      >>> self = FSAFHead(11, 7)
      >>> x = torch.rand(1, 7, 32, 32)
      >>> cls_score, bbox_pred = self.forward_single(x)
      >>> # Each anchor predicts a score for each class except background
      >>> cls_per_anchor = cls_score.shape[1] / self.num_anchors
      >>> box_per_anchor = bbox_pred.shape[1] / self.num_anchors
      >>> assert cls_per_anchor == self.num_classes
      >>> assert box_per_anchor == 4
class_docstr_tok: ["Anchor-free","head","used","in","`","FSAF","<","https",":","\/\/arxiv.org\/abs\/1903.00621",">","`","_",".","The","head","contains","two","subnetworks",".","The","first","classifies","anchor","boxes","and","the","second","regresses","deltas","for","the","anchors","(","num_anchors","is","1","for","anchor-","free","methods",")","Args",":","*","args",":","Same","as","its","base","class","in",":","class",":","`","RetinaHead","`","score_threshold","(","float",",","optional",")",":","The","score_threshold","to","calculate","positive","recall",".","If","given",",","prediction","scores","lower","than","this","value","is","counted","as","incorrect","prediction",".","Default","to","None",".","*","*","kwargs",":","Same","as","its","base","class","in",":","class",":","`","RetinaHead","`","Example",":",">",">",">","import","torch",">",">",">","self","=","FSAFHead","(","11",",","7",")",">",">",">","x","=","torch.rand","(","1",",","7",",","32",",","32",")",">",">",">","cls_score",",","bbox_pred","=","self.forward_single","(","x",")",">",">",">","#","Each","anchor","predicts","a","score","for","each","class","except","background",">",">",">","cls_per_anchor","=","cls_score.shape","[","1","]","\/","self.num_anchors",">",">",">","box_per_anchor","=","bbox_pred.shape","[","1","]","\/","self.num_anchors",">",">",">","assert","cls_per_anchor","==","self.num_classes",">",">",">","assert","box_per_anchor","==","4"]
docstr: Compute regression and classification targets for anchors in a
  single image.
  
  Most of the codes are the same with the base class
    :obj: `AnchorHead`, except that it also collects and returns
    the matched gt index in the image (from 0 to num_gt-1). If the
    anchor bbox is not matched to any gt, the corresponding value in
    pos_gt_inds is -1.
docstr_tok: ["Compute","regression","and","classification","targets","for","anchors","in","a","single","image",".","Most","of","the","codes","are","the","same","with","the","base","class",":","obj",":","`","AnchorHead","`",",","except","that","it","also","collects","and","returns","the","matched","gt","index","in","the","image","(","from","0","to","num_gt-1",")",".","If","the","anchor","bbox","is","not","matched","to","any","gt",",","the","corresponding","value","in","pos_gt_inds","is","-1","."]
code: def _get_targets_single(
      self,
      flat_anchors,
      valid_flags,
      gt_bboxes,
      gt_bboxes_ignore,
      gt_labels,
      img_meta,
      label_channels=1,
      unmap_outputs=True,
  ):
      """Compute regression and classification targets for anchors in a
      single image.
  
      Most of the codes are the same with the base class
        :obj: `AnchorHead`, except that it also collects and returns
        the matched gt index in the image (from 0 to num_gt-1). If the
        anchor bbox is not matched to any gt, the corresponding value in
        pos_gt_inds is -1.
      """
      inside_flags = anchor_inside_flags(
          flat_anchors,
          valid_flags,
          img_meta["img_shape"][:2],
          self.train_cfg.allowed_border,
      )
      if not inside_flags.any():
          return (None,) * 7
      # Assign gt and sample anchors
      anchors = flat_anchors[inside_flags.type(torch.bool), :]
      assign_result = self.assigner.assign(
          anchors,
          gt_bboxes,
          gt_bboxes_ignore,
          None if self.sampling else gt_labels,
      )
  
      sampling_result = self.sampler.sample(
          assign_result, anchors, gt_bboxes
      )
  
      num_valid_anchors = anchors.shape[0]
      bbox_targets = torch.zeros_like(anchors)
      bbox_weights = torch.zeros_like(anchors)
      labels = anchors.new_full(
          (num_valid_anchors,), self.num_classes, dtype=torch.long
      )
      label_weights = anchors.new_zeros(
          (num_valid_anchors, label_channels), dtype=torch.float
      )
      pos_gt_inds = anchors.new_full(
          (num_valid_anchors,), -1, dtype=torch.long
      )
  
      pos_inds = sampling_result.pos_inds
      neg_inds = sampling_result.neg_inds
  
      if len(pos_inds) > 0:
          if not self.reg_decoded_bbox:
              pos_bbox_targets = self.bbox_coder.encode(
                  sampling_result.pos_bboxes,
                  sampling_result.pos_gt_bboxes,
              )
          else:
              pos_bbox_targets = sampling_result.pos_gt_bboxes
          bbox_targets[pos_inds, :] = pos_bbox_targets
          bbox_weights[pos_inds, :] = 1.0
          # The assigned gt_index for each anchor. (0-based)
          pos_gt_inds[pos_inds] = sampling_result.pos_assigned_gt_inds
          if gt_labels is None:
              # Only rpn gives gt_labels as None
              # Foreground is the first class
              labels[pos_inds] = 0
          else:
              labels[pos_inds] = gt_labels[
                  sampling_result.pos_assigned_gt_inds
              ]
          if self.train_cfg.pos_weight <= 0:
              label_weights[pos_inds] = 1.0
          else:
              label_weights[pos_inds] = self.train_cfg.pos_weight
  
      if len(neg_inds) > 0:
          label_weights[neg_inds] = 1.0
  
      # shadowed_labels is a tensor composed of tuples
      #  (anchor_inds, class_label) that indicate those anchors lying in the
      #  outer region of a gt or overlapped by another gt with a smaller
      #  area.
      #
      # Therefore, only the shadowed labels are ignored for loss calculation.
      # the key `shadowed_labels` is defined in :obj:`CenterRegionAssigner`
      shadowed_labels = assign_result.get_extra_property(
          "shadowed_labels"
      )
      if shadowed_labels is not None and shadowed_labels.numel():
          if len(shadowed_labels.shape) == 2:
              idx_, label_ = (
                  shadowed_labels[:, 0],
                  shadowed_labels[:, 1],
              )
              assert (
                  labels[idx_] != label_
              ).all(), "One label cannot be both positive and ignored"
              label_weights[idx_, label_] = 0
          else:
              label_weights[shadowed_labels] = 0
  
      # map up to original set of anchors
      if unmap_outputs:
          num_total_anchors = flat_anchors.size(0)
          labels = unmap(labels, num_total_anchors, inside_flags)
          label_weights = unmap(
              label_weights, num_total_anchors, inside_flags
          )
          bbox_targets = unmap(
              bbox_targets, num_total_anchors, inside_flags
          )
          bbox_weights = unmap(
              bbox_weights, num_total_anchors, inside_flags
          )
          pos_gt_inds = unmap(
              pos_gt_inds, num_total_anchors, inside_flags, fill=-1
          )
  
      return (
          labels,
          label_weights,
          bbox_targets,
          bbox_weights,
          pos_inds,
          neg_inds,
          sampling_result,
          pos_gt_inds,
      )
  
file_path: insightface/detection/scrfd/mmdet/models/dense_heads/fsaf_head.py
imports: import numpy
  import torch
  from mmcv.cnn import normal_init
  from mmcv.runner import force_fp32
  from mmdet.core import anchor_inside_flags, images_to_levels, multi_apply, unmap
  from ..builder import HEADS
  from ..losses.accuracy import accuracy
  from ..losses.utils import weight_reduce_loss
  from .retina_head import RetinaHead
label_desc: Use image node_id 4 for calling the FSAFHead obj's underlying member method code with example usage: obj._get_targets_single(flat_anchors, valid_flags, gt_bboxes, gt_bboxes_ignore, gt_labels, img_meta, label_channels, unmap_outputs) and returns: labels,  label_weights,  bbox_targets,  bbox_weights,  pos_inds,  neg_inds,  sampling_result,  pos_gt_inds, unknown