class_docstr: Implements RetinaNet.
  
  The input to the model is expected to be a list of tensors, each of shape [C, H, W], one for each
  image, and should be in 0-1 range. Different images can have different sizes.
  
  The behavior of the model changes depending if it is in training or evaluation mode.
  
  During training, the model expects both the input tensors, as well as a targets (list of dictionary),
  containing:
      - boxes (``FloatTensor[N, 4]``): the ground-truth boxes in ``[x1, y1, x2, y2]`` format, with
        ``0 <= x1 < x2 <= W`` and ``0 <= y1 < y2 <= H``.
      - labels (Int64Tensor[N]): the class label for each ground-truth box
  
  The model returns a Dict[Tensor] during training, containing the classification and regression
  losses.
  
  During inference, the model requires only the input tensors, and returns the post-processed
  predictions as a List[Dict[Tensor]], one for each input image. The fields of the Dict are as
  follows:
      - boxes (``FloatTensor[N, 4]``): the predicted boxes in ``[x1, y1, x2, y2]`` format, with
        ``0 <= x1 < x2 <= W`` and ``0 <= y1 < y2 <= H``.
      - labels (Int64Tensor[N]): the predicted labels for each image
      - scores (Tensor[N]): the scores for each prediction
  
  Args:
      backbone (nn.Module): the network used to compute the features for the model.
          It should contain an out_channels attribute, which indicates the number of output
          channels that each feature map has (and it should be the same for all feature maps).
          The backbone should return a single Tensor or an OrderedDict[Tensor].
      num_classes (int): number of output classes of the model (excluding the background).
      min_size (int): minimum size of the image to be rescaled before feeding it to the backbone
      max_size (int): maximum size of the image to be rescaled before feeding it to the backbone
      image_mean (Tuple[float, float, float]): mean values used for input normalization.
          They are generally the mean values of the dataset on which the backbone has been trained
          on
      image_std (Tuple[float, float, float]): std values used for input normalization.
          They are generally the std values of the dataset on which the backbone has been trained on
      anchor_generator (AnchorGenerator): module that generates the anchors for a set of feature
          maps.
      head (nn.Module): Module run on top of the feature pyramid.
          Defaults to a module containing a classification and regression module.
      score_thresh (float): Score threshold used for postprocessing the detections.
      nms_thresh (float): NMS threshold used for postprocessing the detections.
      detections_per_img (int): Number of best detections to keep after NMS.
      fg_iou_thresh (float): minimum IoU between the anchor and the GT box so that they can be
          considered as positive during training.
      bg_iou_thresh (float): maximum IoU between the anchor and the GT box so that they can be
          considered as negative during training.
      topk_candidates (int): Number of best detections to keep before NMS.
class_docstr_tok: ["Implements","RetinaNet",".","The","input","to","the","model","is","expected","to","be","a","list","of","tensors",",","each","of","shape","[","C",",","H",",","W","]",",","one","for","each","image",",","and","should","be","in","0-1","range",".","Different","images","can","have","different","sizes",".","The","behavior","of","the","model","changes","depending","if","it","is","in","training","or","evaluation","mode",".","During","training",",","the","model","expects","both","the","input","tensors",",","as","well","as","a","targets","(","list","of","dictionary",")",",","containing",":","-","boxes","(","``","FloatTensor","[","N",",","4","]","``",")",":","the","ground-truth","boxes","in","``","[","x1",",","y1",",","x2",",","y2","]","``","format",",","with","``","0","<","=","x1","<","x2","<","=","W","``","and","``","0","<","=","y1","<","y2","<","=","H","``",".","-","labels","(","Int64Tensor","[","N","]",")",":","the","class","label","for","each","ground-truth","box","The","model","returns","a","Dict","[","Tensor","]","during","training",",","containing","the","classification","and","regression","losses",".","During","inference",",","the","model","requires","only","the","input","tensors",",","and","returns","the","post-processed","predictions","as","a","List","[","Dict","[","Tensor","]","]",",","one","for","each","input","image",".","The","fields","of","the","Dict","are","as","follows",":","-","boxes","(","``","FloatTensor","[","N",",","4","]","``",")",":","the","predicted","boxes","in","``","[","x1",",","y1",",","x2",",","y2","]","``","format",",","with","``","0","<","=","x1","<","x2","<","=","W","``","and","``","0","<","=","y1","<","y2","<","=","H","``",".","-","labels","(","Int64Tensor","[","N","]",")",":","the","predicted","labels","for","each","image","-","scores","(","Tensor","[","N","]",")",":","the","scores","for","each","prediction","Args",":","backbone","(","nn.Module",")",":","the","network","used","to","compute","the","features","for","the","model",".","It","should","contain","an","out_channels","attribute",",","which","indicates","the","number","of","output","channels","that","each","feature","map","has","(","and","it","should","be","the","same","for","all","feature","maps",")",".","The","backbone","should","return","a","single","Tensor","or","an","OrderedDict","[","Tensor","]",".","num_classes","(","int",")",":","number","of","output","classes","of","the","model","(","excluding","the","background",")",".","min_size","(","int",")",":","minimum","size","of","the","image","to","be","rescaled","before","feeding","it","to","the","backbone","max_size","(","int",")",":","maximum","size","of","the","image","to","be","rescaled","before","feeding","it","to","the","backbone","image_mean","(","Tuple","[","float",",","float",",","float","]",")",":","mean","values","used","for","input","normalization",".","They","are","generally","the","mean","values","of","the","dataset","on","which","the","backbone","has","been","trained","on","image_std","(","Tuple","[","float",",","float",",","float","]",")",":","std","values","used","for","input","normalization",".","They","are","generally","the","std","values","of","the","dataset","on","which","the","backbone","has","been","trained","on","anchor_generator","(","AnchorGenerator",")",":","module","that","generates","the","anchors","for","a","set","of","feature","maps",".","head","(","nn.Module",")",":","Module","run","on","top","of","the","feature","pyramid",".","Defaults","to","a","module","containing","a","classification","and","regression","module",".","score_thresh","(","float",")",":","Score","threshold","used","for","postprocessing","the","detections",".","nms_thresh","(","float",")",":","NMS","threshold","used","for","postprocessing","the","detections",".","detections_per_img","(","int",")",":","Number","of","best","detections","to","keep","after","NMS",".","fg_iou_thresh","(","float",")",":","minimum","IoU","between","the","anchor","and","the","GT","box","so","that","they","can","be","considered","as","positive","during","training",".","bg_iou_thresh","(","float",")",":","maximum","IoU","between","the","anchor","and","the","GT","box","so","that","they","can","be","considered","as","negative","during","training",".","topk_candidates","(","int",")",":","Number","of","best","detections","to","keep","before","NMS","."]
code: def postprocess_detections(self, head_output, anchors, image_shapes):
      # type: (Dict[str, List[Tensor]], List[List[Tensor]], List[Tuple[int, int]]) -> List[Dict[str, Tensor]]
      class_logits = head_output["cls_logits"]
      box_regression = head_output["bbox_regression"]
  
      num_img = len(image_shapes)
  
      detections: List[Dict[str, Tensor]] = []
  
      for index in range(num_img):
          box_regression_per_img = [br[index] for br in box_regression]
          logits_per_img = [cl[index] for cl in class_logits]
          anchors_per_img, image_shape = (
              anchors[index],
              image_shapes[index],
          )
  
          img_boxes = []
          img_scores = []
          img_labels = []
  
          for (
              box_regression_per_level,
              logits_per_level,
              anchors_per_level,
          ) in zip(
              box_regression_per_img, logits_per_img, anchors_per_img
          ):
              num_classes = logits_per_level.shape[-1]
  
              # remove low scoring boxes
              # 移除低概率的目标
              scores_per_level = torch.sigmoid(
                  logits_per_level
              ).flatten()
              keep_idxs = torch.gt(
                  scores_per_level, self.score_thresh
              )  # gt: >
              scores_per_level = scores_per_level[keep_idxs]
              topk_idxs = torch.where(keep_idxs)[0]
  
              # keep only topk scoring predictions
              # 在每个level上只取前topk个目标
              num_topk = min(self.topk_candidates, topk_idxs.size(0))
              scores_per_level, idxs = scores_per_level.topk(num_topk)
              topk_idxs = topk_idxs[idxs]
  
              anchor_idxs = topk_idxs // num_classes
              labels_per_level = topk_idxs % num_classes
  
              boxes_per_level = self.box_coder.decode_single(
                  box_regression_per_level[anchor_idxs],
                  anchors_per_level[anchor_idxs],
              )
              boxes_per_level = box_ops.clip_boxes_to_image(
                  boxes_per_level, image_shape
              )
  
              img_boxes.append(boxes_per_level)
              img_scores.append(scores_per_level)
              img_labels.append(labels_per_level)
  
          img_boxes = torch.cat(img_boxes, dim=0)
          img_scores = torch.cat(img_scores, dim=0)
          img_labels = torch.cat(img_labels, dim=0)
  
          # non-maximum suppression
          keep = box_ops.batched_nms(
              img_boxes, img_scores, img_labels, self.nms_thresh
          )
          keep = keep[: self.detections_per_img]
  
          detections.append(
              {
                  "boxes": img_boxes[keep],
                  "scores": img_scores[keep],
                  "labels": img_labels[keep],
              }
          )
  
      return detections
  
imports: import math
  import warnings
  from collections import OrderedDict
  from typing import Dict, List, Tuple, Optional, Union
  import torch
  from torch import nn, Tensor
  from .None import det_utils
  from .anchor_utils import AnchorsGenerator
  from .None import boxes
  from .losses import sigmoid_focal_loss
  from .transform import GeneralizedRCNNTransform
label_desc: Use image node_id 4 for calling the RetinaNet obj's underlying member method code with example usage: obj.postprocess_detections(head_output, anchors, image_shapes) and returns: detections