class_docstr: Implements FCOS.
  
  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, regression
  and centerness 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. For FCOS, only set one anchor for per position of each level, the width and height equal to
          the stride of feature map, and set aspect ratio = 1.0, so the center of anchor is equivalent to the point
          in FCOS paper.
      head (nn.Module): Module run on top of the feature pyramid.
          Defaults to a module containing a classification and regression module.
      center_sampling_radius (int): radius of the "center" of a groundtruth box,
          within which all anchor points are labeled positive.
      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.
      topk_candidates (int): Number of best detections to keep before NMS.
  
  Example:
  
      >>> import torch
      >>> import torchvision
      >>> from torchvision.models.detection import FCOS
      >>> 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
      >>> # FCOS 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=((8,), (16,), (32,), (64,), (128,)),
      >>>     aspect_ratios=((1.0,),)
      >>> )
      >>>
      >>> # put the pieces together inside a FCOS model
      >>> model = FCOS(
      >>>     backbone,
      >>>     num_classes=80,
      >>>     anchor_generator=anchor_generator,
      >>> )
      >>> model.eval()
      >>> x = [torch.rand(3, 300, 400), torch.rand(3, 500, 400)]
      >>> predictions = model(x)
code: def compute_loss(
      self,
      targets: List[Dict[str, Tensor]],
      head_outputs: Dict[str, Tensor],
      anchors: List[Tensor],
      num_anchors_per_level: List[int],
  ) -> Dict[str, Tensor]:
      matched_idxs = []
      for anchors_per_image, targets_per_image in zip(anchors, targets):
          if targets_per_image["boxes"].numel() == 0:
              matched_idxs.append(
                  torch.full(
                      (anchors_per_image.size(0),),
                      -1,
                      dtype=torch.int64,
                      device=anchors_per_image.device,
                  )
              )
              continue
  
          gt_boxes = targets_per_image["boxes"]
          gt_centers = (gt_boxes[:, :2] + gt_boxes[:, 2:]) / 2  # Nx2
          anchor_centers = (
              anchors_per_image[:, :2] + anchors_per_image[:, 2:]
          ) / 2  # N
          anchor_sizes = (
              anchors_per_image[:, 2] - anchors_per_image[:, 0]
          )
          # center sampling: anchor point must be close enough to gt center.
          pairwise_match = (
              anchor_centers[:, None, :] - gt_centers[None, :, :]
          ).abs_().max(
              dim=2
          ).values < self.center_sampling_radius * anchor_sizes[
              :, None
          ]
          # compute pairwise distance between N points and M boxes
          x, y = anchor_centers.unsqueeze(dim=2).unbind(dim=1)  # (N, 1)
          x0, y0, x1, y1 = gt_boxes.unsqueeze(dim=0).unbind(
              dim=2
          )  # (1, M)
          pairwise_dist = torch.stack(
              [x - x0, y - y0, x1 - x, y1 - y], dim=2
          )  # (N, M)
  
          # anchor point must be inside gt
          pairwise_match &= pairwise_dist.min(dim=2).values > 0
  
          # each anchor is only responsible for certain scale range.
          lower_bound = anchor_sizes * 4
          lower_bound[: num_anchors_per_level[0]] = 0
          upper_bound = anchor_sizes * 8
          upper_bound[-num_anchors_per_level[-1] :] = float("inf")
          pairwise_dist = pairwise_dist.max(dim=2).values
          pairwise_match &= (pairwise_dist > lower_bound[:, None]) & (
              pairwise_dist < upper_bound[:, None]
          )
  
          # match the GT box with minimum area, if there are multiple GT matches
          gt_areas = (gt_boxes[:, 2] - gt_boxes[:, 0]) * (
              gt_boxes[:, 3] - gt_boxes[:, 1]
          )  # N
          pairwise_match = pairwise_match.to(torch.float32) * (
              1e8 - gt_areas[None, :]
          )
          min_values, matched_idx = pairwise_match.max(
              dim=1
          )  # R, per-anchor match
          matched_idx[
              min_values < 1e-5
          ] = -1  # unmatched anchors are assigned -1
  
          matched_idxs.append(matched_idx)
  
      return self.head.compute_loss(
          targets, head_outputs, anchors, matched_idxs
      )
  
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, generalized_box_iou_loss, 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 .anchor_utils import AnchorGenerator
  from .backbone_utils import _resnet_fpn_extractor, _validate_trainable_layers
  from .transform import GeneralizedRCNNTransform
label_desc: Use image node_id 3 for calling the FCOS obj's underlying member method code with example usage: obj.compute_loss(targets, head_outputs, anchors, num_anchors_per_level) and returns: self