class_docstr: Retinanet detector, expandable to other one stage anchor based box detectors in the future.
  An example of construction can found in the source code of
  :func:`~monai.apps.detection.networks.retinanet_detector.retinanet_resnet50_fpn_detector` .
  
  The input to the model is expected to be a list of tensors, each of shape (C, H, W) or  (C, H, W, D),
  one for each image, and should be in 0-1 range. Different images can have different sizes.
  Or it can also be a Tensor sized (B, C, H, W) or  (B, C, H, W, D). In this case, all images have same size.
  
  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]`` or ``FloatTensor[N, 6]``): the ground-truth boxes in ``StandardMode``, i.e.,
    ``[xmin, ymin, xmax, ymax]`` or ``[xmin, ymin, zmin, xmax, ymax, zmax]`` format,
    with ``0 <= xmin < xmax <= H``, ``0 <= ymin < ymax <= W``, ``0 <= zmin < zmax <= D``.
  - labels: the class label for each ground-truth box
  
  The model returns a Dict[str, Tensor] during training, containing the classification and regression
  losses.
  When saving the model, only self.network contains trainable parameters and needs to be saved.
  
  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]`` or ``FloatTensor[N, 6]``): the predicted boxes in ``StandardMode``, i.e.,
    ``[xmin, ymin, xmax, ymax]`` or ``[xmin, ymin, zmin, xmax, ymax, zmax]`` format,
    with ``0 <= xmin < xmax <= H``, ``0 <= ymin < ymax <= W``, ``0 <= zmin < zmax <= D``.
  - labels (Int64Tensor[N]): the predicted labels for each image
  - labels_scores (Tensor[N]): the scores for each prediction
  
  Args:
      network: a network that takes an image Tensor sized (B, C, H, W) or (B, C, H, W, D) as input
          and outputs a dictionary Dict[str, List[Tensor]] or Dict[str, Tensor].
      anchor_generator: anchor generator.
      box_overlap_metric: func that compute overlap between two sets of boxes, default is Intersection over Union (IoU).
      debug: whether to print out internal parameters, used for debugging and parameter tuning.
  
  Notes:
  
      Input argument ``network`` can be a monai.apps.detection.networks.retinanet_network.RetinaNet(*) object,
      but any network that meets the following rules is a valid input ``network``.
  
      1. It should have attributes including spatial_dims, num_classes, cls_key, box_reg_key, num_anchors, size_divisible.
  
          - spatial_dims (int) is the spatial dimension of the network, we support both 2D and 3D.
          - num_classes (int) is the number of classes, excluding the background.
          - size_divisible (int or Sequence[int]) is the expectation on the input image shape.
            The network needs the input spatial_size to be divisible by size_divisible, length should be 2 or 3.
          - cls_key (str) is the key to represent classification in the output dict.
          - box_reg_key (str) is the key to represent box regression in the output dict.
          - num_anchors (int) is the number of anchor shapes at each location. it should equal to
            ``self.anchor_generator.num_anchors_per_location()[0]``.
  
          If network does not have these attributes, user needs to provide them for the detector.
  
      2. Its input should be an image Tensor sized (B, C, H, W) or (B, C, H, W, D).
  
      3. About its output ``head_outputs``, it should be either a list of tensors or a dictionary of str: List[Tensor]:
  
          - If it is a dictionary, it needs to have at least two keys:
            ``network.cls_key`` and ``network.box_reg_key``, representing predicted classification maps and box regression maps.
            ``head_outputs[network.cls_key]`` should be List[Tensor] or Tensor. Each Tensor represents
            classification logits map at one resolution level,
            sized (B, num_classes*num_anchors, H_i, W_i) or (B, num_classes*num_anchors, H_i, W_i, D_i).
            ``head_outputs[network.box_reg_key]`` should be List[Tensor] or Tensor. Each Tensor represents
            box regression map at one resolution level,
            sized (B, 2*spatial_dims*num_anchors, H_i, W_i)or (B, 2*spatial_dims*num_anchors, H_i, W_i, D_i).
            ``len(head_outputs[network.cls_key]) == len(head_outputs[network.box_reg_key])``.
          - If it is a list of 2N tensors, the first N tensors should be the predicted classification maps,
            and the second N tensors should be the predicted box regression maps.
  
  Example:
  
      .. code-block:: python
  
          # define a naive network
          import torch
          class NaiveNet(torch.nn.Module):
              def __init__(self, spatial_dims: int, num_classes: int):
                  super().__init__()
                  self.spatial_dims = spatial_dims
                  self.num_classes = num_classes
                  self.size_divisible = 2
                  self.cls_key = "cls"
                  self.box_reg_key = "box_reg"
                  self.num_anchors = 1
              def forward(self, images: torch.Tensor):
                  spatial_size = images.shape[-self.spatial_dims:]
                  out_spatial_size = tuple(s//self.size_divisible for s in spatial_size)  # half size of input
                  out_cls_shape = (images.shape[0],self.num_classes*self.num_anchors) + out_spatial_size
                  out_box_reg_shape = (images.shape[0],2*self.spatial_dims*self.num_anchors) + out_spatial_size
                  return {self.cls_key: [torch.randn(out_cls_shape)], self.box_reg_key: [torch.randn(out_box_reg_shape)]}
  
          # create a RetinaNetDetector detector
          spatial_dims = 3
          num_classes = 5
          anchor_generator = monai.apps.detection.utils.anchor_utils.AnchorGeneratorWithAnchorShape(
              feature_map_scales=(1, ), base_anchor_shapes=((8,) * spatial_dims)
          )
          net = NaiveNet(spatial_dims, num_classes)
          detector = RetinaNetDetector(net, anchor_generator)
  
          # only detector.network may contain trainable parameters.
          optimizer = torch.optim.SGD(
              detector.network.parameters(),
              1e-3,
              momentum=0.9,
              weight_decay=3e-5,
              nesterov=True,
          )
          torch.save(detector.network.state_dict(), 'model.pt')  # save model
          detector.network.load_state_dict(torch.load('model.pt'))  # load model
class_docstr_tok: ["Retinanet","detector",",","expandable","to","other","one","stage","anchor","based","box","detectors","in","the","future",".","An","example","of","construction","can","found","in","the","source","code","of",":","func",":","`","~monai.apps.detection.networks.retinanet_detector.retinanet_resnet50_fpn_detector","`",".","The","input","to","the","model","is","expected","to","be","a","list","of","tensors",",","each","of","shape","(","C",",","H",",","W",")","or","(","C",",","H",",","W",",","D",")",",","one","for","each","image",",","and","should","be","in","0-1","range",".","Different","images","can","have","different","sizes",".","Or","it","can","also","be","a","Tensor","sized","(","B",",","C",",","H",",","W",")","or","(","B",",","C",",","H",",","W",",","D",")",".","In","this","case",",","all","images","have","same","size",".","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","]","``","or","``","FloatTensor","[","N",",","6","]","``",")",":","the","ground-truth","boxes","in","``","StandardMode","``",",","i.e.",",","``","[","xmin",",","ymin",",","xmax",",","ymax","]","``","or","``","[","xmin",",","ymin",",","zmin",",","xmax",",","ymax",",","zmax","]","``","format",",","with","``","0","<","=","xmin","<","xmax","<","=","H","``",",","``","0","<","=","ymin","<","ymax","<","=","W","``",",","``","0","<","=","zmin","<","zmax","<","=","D","``",".","-","labels",":","the","class","label","for","each","ground-truth","box","The","model","returns","a","Dict","[","str",",","Tensor","]","during","training",",","containing","the","classification","and","regression","losses",".","When","saving","the","model",",","only","self.network","contains","trainable","parameters","and","needs","to","be","saved",".","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","]","``","or","``","FloatTensor","[","N",",","6","]","``",")",":","the","predicted","boxes","in","``","StandardMode","``",",","i.e.",",","``","[","xmin",",","ymin",",","xmax",",","ymax","]","``","or","``","[","xmin",",","ymin",",","zmin",",","xmax",",","ymax",",","zmax","]","``","format",",","with","``","0","<","=","xmin","<","xmax","<","=","H","``",",","``","0","<","=","ymin","<","ymax","<","=","W","``",",","``","0","<","=","zmin","<","zmax","<","=","D","``",".","-","labels","(","Int64Tensor","[","N","]",")",":","the","predicted","labels","for","each","image","-","labels_scores","(","Tensor","[","N","]",")",":","the","scores","for","each","prediction","Args",":","network",":","a","network","that","takes","an","image","Tensor","sized","(","B",",","C",",","H",",","W",")","or","(","B",",","C",",","H",",","W",",","D",")","as","input","and","outputs","a","dictionary","Dict","[","str",",","List","[","Tensor","]","]","or","Dict","[","str",",","Tensor","]",".","anchor_generator",":","anchor","generator",".","box_overlap_metric",":","func","that","compute","overlap","between","two","sets","of","boxes",",","default","is","Intersection","over","Union","(","IoU",")",".","debug",":","whether","to","print","out","internal","parameters",",","used","for","debugging","and","parameter","tuning",".","Notes",":","Input","argument","``","network","``","can","be","a","monai.apps.detection.networks.retinanet_network.RetinaNet","(","*",")","object",",","but","any","network","that","meets","the","following","rules","is","a","valid","input","``","network","``",".","1",".","It","should","have","attributes","including","spatial_dims",",","num_classes",",","cls_key",",","box_reg_key",",","num_anchors",",","size_divisible",".","-","spatial_dims","(","int",")","is","the","spatial","dimension","of","the","network",",","we","support","both","2D","and","3D",".","-","num_classes","(","int",")","is","the","number","of","classes",",","excluding","the","background",".","-","size_divisible","(","int","or","Sequence","[","int","]",")","is","the","expectation","on","the","input","image","shape",".","The","network","needs","the","input","spatial_size","to","be","divisible","by","size_divisible",",","length","should","be","2","or","3",".","-","cls_key","(","str",")","is","the","key","to","represent","classification","in","the","output","dict",".","-","box_reg_key","(","str",")","is","the","key","to","represent","box","regression","in","the","output","dict",".","-","num_anchors","(","int",")","is","the","number","of","anchor","shapes","at","each","location",".","it","should","equal","to","``","self.anchor_generator.num_anchors_per_location","(",")","[","0","]","``",".","If","network","does","not","have","these","attributes",",","user","needs","to","provide","them","for","the","detector",".","2",".","Its","input","should","be","an","image","Tensor","sized","(","B",",","C",",","H",",","W",")","or","(","B",",","C",",","H",",","W",",","D",")",".","3",".","About","its","output","``","head_outputs","``",",","it","should","be","either","a","list","of","tensors","or","a","dictionary","of","str",":","List","[","Tensor","]",":","-","If","it","is","a","dictionary",",","it","needs","to","have","at","least","two","keys",":","``","network.cls_key","``","and","``","network.box_reg_key","``",",","representing","predicted","classification","maps","and","box","regression","maps",".","``","head_outputs","[","network.cls_key","]","``","should","be","List","[","Tensor","]","or","Tensor",".","Each","Tensor","represents","classification","logits","map","at","one","resolution","level",",","sized","(","B",",","num_classes","*","num_anchors",",","H_i",",","W_i",")","or","(","B",",","num_classes","*","num_anchors",",","H_i",",","W_i",",","D_i",")",".","``","head_outputs","[","network.box_reg_key","]","``","should","be","List","[","Tensor","]","or","Tensor",".","Each","Tensor","represents","box","regression","map","at","one","resolution","level",",","sized","(","B",",","2","*","spatial_dims","*","num_anchors",",","H_i",",","W_i",")","or","(","B",",","2","*","spatial_dims","*","num_anchors",",","H_i",",","W_i",",","D_i",")",".","``","len","(","head_outputs","[","network.cls_key","]",")","==","len","(","head_outputs","[","network.box_reg_key","]",")","``",".","-","If","it","is","a","list","of","2N","tensors",",","the","first","N","tensors","should","be","the","predicted","classification","maps",",","and","the","second","N","tensors","should","be","the","predicted","box","regression","maps",".","Example",":","..","code-block",":",":","python","#","define","a","naive","network","import","torch","class","NaiveNet","(","torch.nn.Module",")",":","def","__init__","(","self",",","spatial_dims",":","int",",","num_classes",":","int",")",":","super","(",")",".__init__","(",")","self.spatial_dims","=","spatial_dims","self.num_classes","=","num_classes","self.size_divisible","=","2","self.cls_key","=","``","cls","''","self.box_reg_key","=","``","box_reg","''","self.num_anchors","=","1","def","forward","(","self",",","images",":","torch.Tensor",")",":","spatial_size","=","images.shape","[","-self.spatial_dims",":","]","out_spatial_size","=","tuple","(","s\/\/self.size_divisible","for","s","in","spatial_size",")","#","half","size","of","input","out_cls_shape","=","(","images.shape","[","0","]",",","self.num_classes","*","self.num_anchors",")","+","out_spatial_size","out_box_reg_shape","=","(","images.shape","[","0","]",",2","*","self.spatial_dims","*","self.num_anchors",")","+","out_spatial_size","return","{","self.cls_key",":","[","torch.randn","(","out_cls_shape",")","]",",","self.box_reg_key",":","[","torch.randn","(","out_box_reg_shape",")","]","}","#","create","a","RetinaNetDetector","detector","spatial_dims","=","3","num_classes","=","5","anchor_generator","=","monai.apps.detection.utils.anchor_utils.AnchorGeneratorWithAnchorShape","(","feature_map_scales=","(","1",",",")",",","base_anchor_shapes=","(","(","8",",",")","*","spatial_dims",")",")","net","=","NaiveNet","(","spatial_dims",",","num_classes",")","detector","=","RetinaNetDetector","(","net",",","anchor_generator",")","#","only","detector.network","may","contain","trainable","parameters",".","optimizer","=","torch.optim.SGD","(","detector.network.parameters","(",")",",","1e-3",",","momentum=0.9",",","weight_decay=3e-5",",","nesterov=True",",",")","torch.save","(","detector.network.state_dict","(",")",",","'model.pt","'",")","#","save","model","detector.network.load_state_dict","(","torch.load","(","'model.pt","'",")",")","#","load","model"]
docstr: Check if self.proposal_matcher and self.fg_bg_sampler have been set for training.
code: def _check_detector_training_components(self):
      """
      Check if self.proposal_matcher and self.fg_bg_sampler have been set for training.
      """
      if not hasattr(self, "proposal_matcher"):
          raise AttributeError(
              "Matcher is not set. Please refer to self.set_regular_matcher(*) or self.set_atss_matcher(*)."
          )
      if self.fg_bg_sampler is None and self.debug:
          warnings.warn(
              "No balanced sampler is used. Negative samples are likely to "
              "be much more than positive samples. Please set balanced samplers with self.set_balanced_sampler(*) "
              "or self.set_hard_negative_sampler(*), "
              "or set classification loss function as Focal loss with self.set_cls_loss(*)"
          )
  
imports: from __future__ import annotations
  import warnings
  from collections.abc import Callable, Sequence
  from typing import Any
  import torch
  from torch import Tensor, nn
  from monai.apps.detection.networks.retinanet_network import RetinaNet, resnet_fpn_feature_extractor
  from monai.apps.detection.utils.anchor_utils import AnchorGenerator
  from monai.apps.detection.utils.ATSS_matcher import ATSSMatcher
  from monai.apps.detection.utils.box_coder import BoxCoder
  from monai.apps.detection.utils.box_selector import BoxSelector
  from monai.apps.detection.utils.detector_utils import check_training_targets, preprocess_images
  from monai.apps.detection.utils.hard_negative_sampler import HardNegativeSampler
  from monai.apps.detection.utils.predict_utils import ensure_dict_value_to_list_, predict_with_inferer
  from monai.data.box_utils import box_iou
  from monai.inferers import SlidingWindowInferer
  from monai.networks.nets import resnet
  from monai.utils import BlendMode, PytorchPadMode, ensure_tuple_rep, optional_import
label_desc: Use image node_id 14 for calling the RetinaNetDetector obj's underlying member method code with example usage: obj._check_detector_training_components() without return types