class_docstr: TOODHead used in `TOOD: Task-aligned One-stage Object Detection.
  
  <https://arxiv.org/abs/2108.07755>`_.
  
  TOOD uses Task-aligned head (T-head) and is optimized by Task Alignment
  Learning (TAL).
  
  Args:
      num_classes (int): Number of categories excluding the background
          category.
      in_channels (int): Number of channels in the input feature map.
      num_dcn (int): Number of deformable convolution in the head.
          Defaults to 0.
      anchor_type (str): If set to ``anchor_free``, the head will use centers
          to regress bboxes. If set to ``anchor_based``, the head will
          regress bboxes based on anchors. Defaults to ``anchor_free``.
      initial_loss_cls (:obj:`ConfigDict` or dict): Config of initial loss.
  
  Example:
      >>> self = TOODHead(11, 7)
      >>> feats = [torch.rand(1, 7, s, s) for s in [4, 8, 16, 32, 64]]
      >>> cls_score, bbox_pred = self.forward(feats)
      >>> assert len(cls_score) == len(self.scales)
class_docstr_tok: ["TOODHead","used","in","`","TOOD",":","Task-aligned","One-stage","Object","Detection",".","<","https",":","\/\/arxiv.org\/abs\/2108.07755",">","`","_",".","TOOD","uses","Task-aligned","head","(","T-head",")","and","is","optimized","by","Task","Alignment","Learning","(","TAL",")",".","Args",":","num_classes","(","int",")",":","Number","of","categories","excluding","the","background","category",".","in_channels","(","int",")",":","Number","of","channels","in","the","input","feature","map",".","num_dcn","(","int",")",":","Number","of","deformable","convolution","in","the","head",".","Defaults","to","0.","anchor_type","(","str",")",":","If","set","to","``","anchor_free","``",",","the","head","will","use","centers","to","regress","bboxes",".","If","set","to","``","anchor_based","``",",","the","head","will","regress","bboxes","based","on","anchors",".","Defaults","to","``","anchor_free","``",".","initial_loss_cls","(",":","obj",":","`","ConfigDict","`","or","dict",")",":","Config","of","initial","loss",".","Example",":",">",">",">","self","=","TOODHead","(","11",",","7",")",">",">",">","feats","=","[","torch.rand","(","1",",","7",",","s",",","s",")","for","s","in","[","4",",","8",",","16",",","32",",","64","]","]",">",">",">","cls_score",",","bbox_pred","=","self.forward","(","feats",")",">",">",">","assert","len","(","cls_score",")","==","len","(","self.scales",")"]
docstr: Calculate the loss of a single scale level based on the features
  extracted by the detection head.
  
  Args:
      anchors (Tensor): Box reference for each scale level with shape
          (N, num_total_anchors, 4).
      cls_score (Tensor): Box scores for each scale level
          Has shape (N, num_anchors * num_classes, H, W).
      bbox_pred (Tensor): Decoded bboxes for each scale
          level with shape (N, num_anchors * 4, H, W).
      labels (Tensor): Labels of each anchors with shape
          (N, num_total_anchors).
      label_weights (Tensor): Label weights of each anchor with shape
          (N, num_total_anchors).
      bbox_targets (Tensor): BBox regression targets of each anchor with
          shape (N, num_total_anchors, 4).
      alignment_metrics (Tensor): Alignment metrics with shape
          (N, num_total_anchors).
      stride (Tuple[int, int]): Downsample stride of the feature map.
  
  Returns:
      dict[str, Tensor]: A dictionary of loss components.
docstr_tok: ["Calculate","the","loss","of","a","single","scale","level","based","on","the","features","extracted","by","the","detection","head",".","Args",":","anchors","(","Tensor",")",":","Box","reference","for","each","scale","level","with","shape","(","N",",","num_total_anchors",",","4",")",".","cls_score","(","Tensor",")",":","Box","scores","for","each","scale","level","Has","shape","(","N",",","num_anchors","*","num_classes",",","H",",","W",")",".","bbox_pred","(","Tensor",")",":","Decoded","bboxes","for","each","scale","level","with","shape","(","N",",","num_anchors","*","4",",","H",",","W",")",".","labels","(","Tensor",")",":","Labels","of","each","anchors","with","shape","(","N",",","num_total_anchors",")",".","label_weights","(","Tensor",")",":","Label","weights","of","each","anchor","with","shape","(","N",",","num_total_anchors",")",".","bbox_targets","(","Tensor",")",":","BBox","regression","targets","of","each","anchor","with","shape","(","N",",","num_total_anchors",",","4",")",".","alignment_metrics","(","Tensor",")",":","Alignment","metrics","with","shape","(","N",",","num_total_anchors",")",".","stride","(","Tuple","[","int",",","int","]",")",":","Downsample","stride","of","the","feature","map",".","Returns",":","dict","[","str",",","Tensor","]",":","A","dictionary","of","loss","components","."]
code: def loss_by_feat_single(
      self,
      anchors: Tensor,
      cls_score: Tensor,
      bbox_pred: Tensor,
      labels: Tensor,
      label_weights: Tensor,
      bbox_targets: Tensor,
      alignment_metrics: Tensor,
      stride: Tuple[int, int],
  ) -> dict:
      """Calculate the loss of a single scale level based on the features
      extracted by the detection head.
  
      Args:
          anchors (Tensor): Box reference for each scale level with shape
              (N, num_total_anchors, 4).
          cls_score (Tensor): Box scores for each scale level
              Has shape (N, num_anchors * num_classes, H, W).
          bbox_pred (Tensor): Decoded bboxes for each scale
              level with shape (N, num_anchors * 4, H, W).
          labels (Tensor): Labels of each anchors with shape
              (N, num_total_anchors).
          label_weights (Tensor): Label weights of each anchor with shape
              (N, num_total_anchors).
          bbox_targets (Tensor): BBox regression targets of each anchor with
              shape (N, num_total_anchors, 4).
          alignment_metrics (Tensor): Alignment metrics with shape
              (N, num_total_anchors).
          stride (Tuple[int, int]): Downsample stride of the feature map.
  
      Returns:
          dict[str, Tensor]: A dictionary of loss components.
      """
      assert (
          stride[0] == stride[1]
      ), "h stride is not equal to w stride!"
      anchors = anchors.reshape(-1, 4)
      cls_score = (
          cls_score.permute(0, 2, 3, 1)
          .reshape(-1, self.cls_out_channels)
          .contiguous()
      )
      bbox_pred = bbox_pred.permute(0, 2, 3, 1).reshape(-1, 4)
      bbox_targets = bbox_targets.reshape(-1, 4)
      labels = labels.reshape(-1)
      alignment_metrics = alignment_metrics.reshape(-1)
      label_weights = label_weights.reshape(-1)
      targets = (
          labels
          if self.epoch < self.initial_epoch
          else (labels, alignment_metrics)
      )
      cls_loss_func = (
          self.initial_loss_cls
          if self.epoch < self.initial_epoch
          else self.loss_cls
      )
  
      loss_cls = cls_loss_func(
          cls_score, targets, label_weights, avg_factor=1.0
      )
  
      # FG cat_id: [0, num_classes -1], BG cat_id: num_classes
      bg_class_ind = self.num_classes
      pos_inds = (
          ((labels >= 0) & (labels < bg_class_ind)).nonzero().squeeze(1)
      )
  
      if len(pos_inds) > 0:
          pos_bbox_targets = bbox_targets[pos_inds]
          pos_bbox_pred = bbox_pred[pos_inds]
          pos_anchors = anchors[pos_inds]
  
          pos_decode_bbox_pred = pos_bbox_pred
          pos_decode_bbox_targets = pos_bbox_targets / stride[0]
  
          # regression loss
          pos_bbox_weight = (
              self.centerness_target(pos_anchors, pos_bbox_targets)
              if self.epoch < self.initial_epoch
              else alignment_metrics[pos_inds]
          )
  
          loss_bbox = self.loss_bbox(
              pos_decode_bbox_pred,
              pos_decode_bbox_targets,
              weight=pos_bbox_weight,
              avg_factor=1.0,
          )
      else:
          loss_bbox = bbox_pred.sum() * 0
          pos_bbox_weight = bbox_targets.new_tensor(0.0)
  
      return (
          loss_cls,
          loss_bbox,
          alignment_metrics.sum(),
          pos_bbox_weight.sum(),
      )
  
imports: from typing import List, Optional, Tuple
  import torch
  import torch.nn
  import torch.nn.functional
  from mmcv.cnn import ConvModule, Scale
  from mmcv.ops import deform_conv2d
  from mmengine import MessageHub
  from mmengine.config import ConfigDict
  from mmengine.model import bias_init_with_prob, normal_init
  from mmengine.structures import InstanceData
  from torch import Tensor
  from mmdet.registry import MODELS, TASK_UTILS
  from mmdet.structures.bbox import distance2bbox
  from mmdet.utils import ConfigType, InstanceList, OptConfigType, OptInstanceList, reduce_mean
  from ..task_modules.prior_generators import anchor_inside_flags
  from ..utils import filter_scores_and_topk, images_to_levels, multi_apply, sigmoid_geometric_mean, unmap
  from .atss_head import ATSSHead
label_desc: Use image node_id 7 for calling the TOODHead obj's underlying member method code with example usage: obj.loss_by_feat_single(anchors, cls_score, bbox_pred, labels, label_weights, bbox_targets, alignment_metrics, stride) and returns: loss_cls,  loss_bbox,  alignment_metrics,  pos_bbox_weight