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 on if it is in training or evaluation mode.
  
  During training, the model expects both the input tensors and 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 (including 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.
  
  Example:
  
      >>> import torch
      >>> import torchvision
      >>> from torchvision.models.detection import RetinaNet
      >>> from torchvision.models.detection.anchor_utils import AnchorGenerator
      >>> # load a pre-trained model for classification and return
      >>> # only the features
      >>> backbone = torchvision.models.mobilenet_v2(weights=MobileNet_V2_Weights.DEFAULT).features
      >>> # RetinaNet needs to know the number of
      >>> # output channels in a backbone. For mobilenet_v2, it's 1280,
      >>> # so we need to add it here
      >>> backbone.out_channels = 1280
      >>>
      >>> # let's make the network generate 5 x 3 anchors per spatial
      >>> # location, with 5 different sizes and 3 different aspect
      >>> # ratios. We have a Tuple[Tuple[int]] because each feature
      >>> # map could potentially have different sizes and
      >>> # aspect ratios
      >>> anchor_generator = AnchorGenerator(
      >>>     sizes=((32, 64, 128, 256, 512),),
      >>>     aspect_ratios=((0.5, 1.0, 2.0),)
      >>> )
      >>>
      >>> # put the pieces together inside a RetinaNet model
      >>> model = RetinaNet(backbone,
      >>>                   num_classes=2,
      >>>                   anchor_generator=anchor_generator)
      >>> model.eval()
      >>> x = [torch.rand(3, 300, 400), torch.rand(3, 500, 400)]
      >>> predictions = model(x)
docstr: Args:
      images (list[Tensor]): images to be processed
      targets (list[Dict[Tensor]]): ground-truth boxes present in the image (optional)
  
  Returns:
      result (list[BoxList] or dict[Tensor]): the output from the model.
          During training, it returns a dict[Tensor] which contains the losses.
          During testing, it returns list[BoxList] contains additional fields
          like `scores`, `labels` and `mask` (for Mask R-CNN models).
docstr_tok: ["Args",":","images","(","list","[","Tensor","]",")",":","images","to","be","processed","targets","(","list","[","Dict","[","Tensor","]","]",")",":","ground-truth","boxes","present","in","the","image","(","optional",")","Returns",":","result","(","list","[","BoxList","]","or","dict","[","Tensor","]",")",":","the","output","from","the","model",".","During","training",",","it","returns","a","dict","[","Tensor","]","which","contains","the","losses",".","During","testing",",","it","returns","list","[","BoxList","]","contains","additional","fields","like","`","scores","`",",","`","labels","`","and","`","mask","`","(","for","Mask","R-CNN","models",")","."]
code: def forward(self, images, targets=None):
      # type: (List[Tensor], Optional[List[Dict[str, Tensor]]]) -> Tuple[Dict[str, Tensor], List[Dict[str, Tensor]]]
      """
      Args:
          images (list[Tensor]): images to be processed
          targets (list[Dict[Tensor]]): ground-truth boxes present in the image (optional)
  
      Returns:
          result (list[BoxList] or dict[Tensor]): the output from the model.
              During training, it returns a dict[Tensor] which contains the losses.
              During testing, it returns list[BoxList] contains additional fields
              like `scores`, `labels` and `mask` (for Mask R-CNN models).
  
      """
      if self.training:
          if targets is None:
              torch._assert(
                  False,
                  "targets should not be none when in training mode",
              )
          else:
              for target in targets:
                  boxes = target["boxes"]
                  torch._assert(
                      isinstance(boxes, torch.Tensor),
                      "Expected target boxes to be of type Tensor.",
                  )
                  torch._assert(
                      len(boxes.shape) == 2 and boxes.shape[-1] == 4,
                      "Expected target boxes to be a tensor of shape [N, 4].",
                  )
  
      # get the original image sizes
      original_image_sizes: List[Tuple[int, int]] = []
      for img in images:
          val = img.shape[-2:]
          torch._assert(
              len(val) == 2,
              f"expecting the last two dimensions of the Tensor to be H and W instead got {img.shape[-2:]}",
          )
          original_image_sizes.append((val[0], val[1]))
  
      # transform the input
      images, targets = self.transform(images, targets)
  
      # Check for degenerate boxes
      # TODO: Move this to a function
      if targets is not None:
          for target_idx, target in enumerate(targets):
              boxes = target["boxes"]
              degenerate_boxes = boxes[:, 2:] <= boxes[:, :2]
              if degenerate_boxes.any():
                  # print the first degenerate box
                  bb_idx = torch.where(degenerate_boxes.any(dim=1))[0][
                      0
                  ]
                  degen_bb: List[float] = boxes[bb_idx].tolist()
                  torch._assert(
                      False,
                      "All bounding boxes should have positive height and width."
                      f" Found invalid box {degen_bb} for target at index {target_idx}.",
                  )
  
      # get the features from the backbone
      features = self.backbone(images.tensors)
      if isinstance(features, torch.Tensor):
          features = OrderedDict([("0", features)])
  
      # TODO: Do we want a list or a dict?
      features = list(features.values())
  
      # compute the retinanet heads outputs using the features
      head_outputs = self.head(features)
  
      # create the set of anchors
      anchors = self.anchor_generator(images, features)
  
      losses = {}
      detections: List[Dict[str, Tensor]] = []
      if self.training:
          if targets is None:
              torch._assert(
                  False,
                  "targets should not be none when in training mode",
              )
          else:
              # compute the losses
              losses = self.compute_loss(targets, head_outputs, anchors)
      else:
          # recover level sizes
          num_anchors_per_level = [
              x.size(2) * x.size(3) for x in features
          ]
          HW = 0
          for v in num_anchors_per_level:
              HW += v
          HWA = head_outputs["cls_logits"].size(1)
          A = HWA // HW
          num_anchors_per_level = [
              hw * A for hw in num_anchors_per_level
          ]
  
          # split outputs per level
          split_head_outputs: Dict[str, List[Tensor]] = {}
          for k in head_outputs:
              split_head_outputs[k] = list(
                  head_outputs[k].split(num_anchors_per_level, dim=1)
              )
          split_anchors = [
              list(a.split(num_anchors_per_level)) for a in anchors
          ]
  
          # compute the detections
          detections = self.postprocess_detections(
              split_head_outputs, split_anchors, images.image_sizes
          )
          detections = self.transform.postprocess(
              detections, images.image_sizes, original_image_sizes
          )
  
      if torch.jit.is_scripting():
          if not self._has_warned:
              warnings.warn(
                  "RetinaNet always returns a (Losses, Detections) tuple in scripting"
              )
              self._has_warned = True
          return losses, detections
      return self.eager_outputs(losses, detections)
  
imports: import math
  import warnings
  from collections import OrderedDict
  from functools import partial
  from typing import Any, Callable, Dict, List, Optional, Tuple
  import torch
  from torch import nn, Tensor
  from ...ops import boxes, misc, sigmoid_focal_loss
  from ...ops.feature_pyramid_network import LastLevelP6P7
  from ...transforms._presets import ObjectDetection
  from ...utils import _log_api_usage_once
  from .._api import register_model, Weights, WeightsEnum
  from .._meta import _COCO_CATEGORIES
  from .._utils import _ovewrite_value_param, handle_legacy_interface
  from ..resnet import resnet50, ResNet50_Weights
  from .None import _utils
  from ._utils import _box_loss, overwrite_eps
  from .anchor_utils import AnchorGenerator
  from .backbone_utils import _resnet_fpn_extractor, _validate_trainable_layers
  from .transform import GeneralizedRCNNTransform
label_desc: Use image node_id 5 for calling the RetinaNet obj's underlying member method code with example usage: obj.forward(images, targets) and returns: self, losses,  detections