class_docstr: Anchor generator for SSD.
  
  Args:
      strides (list[int]  | list[tuple[int, int]]): Strides of anchors
          in multiple feature levels.
      ratios (list[float]): The list of ratios between the height and width
          of anchors in a single level.
      min_sizes (list[float]): The list of minimum anchor sizes on each
          level.
      max_sizes (list[float]): The list of maximum anchor sizes on each
          level.
      basesize_ratio_range (tuple(float)): Ratio range of anchors. Being
          used when not setting min_sizes and max_sizes.
      input_size (int): Size of feature map, 300 for SSD300, 512 for
          SSD512. Being used when not setting min_sizes and max_sizes.
      scale_major (bool): Whether to multiply scales first when generating
          base anchors. If true, the anchors in the same row will have the
          same scales. It is always set to be False in SSD.
      use_box_type (bool): Whether to warp anchors with the box type data
          structure. Defaults to False.
class_docstr_tok: ["Anchor","generator","for","SSD",".","Args",":","strides","(","list","[","int","]","|","list","[","tuple","[","int",",","int","]","]",")",":","Strides","of","anchors","in","multiple","feature","levels",".","ratios","(","list","[","float","]",")",":","The","list","of","ratios","between","the","height","and","width","of","anchors","in","a","single","level",".","min_sizes","(","list","[","float","]",")",":","The","list","of","minimum","anchor","sizes","on","each","level",".","max_sizes","(","list","[","float","]",")",":","The","list","of","maximum","anchor","sizes","on","each","level",".","basesize_ratio_range","(","tuple","(","float",")",")",":","Ratio","range","of","anchors",".","Being","used","when","not","setting","min_sizes","and","max_sizes",".","input_size","(","int",")",":","Size","of","feature","map",",","300","for","SSD300",",","512","for","SSD512",".","Being","used","when","not","setting","min_sizes","and","max_sizes",".","scale_major","(","bool",")",":","Whether","to","multiply","scales","first","when","generating","base","anchors",".","If","true",",","the","anchors","in","the","same","row","will","have","the","same","scales",".","It","is","always","set","to","be","False","in","SSD",".","use_box_type","(","bool",")",":","Whether","to","warp","anchors","with","the","box","type","data","structure",".","Defaults","to","False","."]
code: def __init__(
      self,
      strides: Union[List[int], List[Tuple[int, int]]],
      ratios: List[float],
      min_sizes: Optional[List[float]] = None,
      max_sizes: Optional[List[float]] = None,
      basesize_ratio_range: Tuple[float] = (0.15, 0.9),
      input_size: int = 300,
      scale_major: bool = True,
      use_box_type: bool = False,
  ) -> None:
      assert len(strides) == len(ratios)
      assert not (min_sizes is None) ^ (max_sizes is None)
      self.strides = [_pair(stride) for stride in strides]
      self.centers = [
          (stride[0] / 2.0, stride[1] / 2.0) for stride in self.strides
      ]
  
      if min_sizes is None and max_sizes is None:
          # use hard code to generate SSD anchors
          self.input_size = input_size
          assert is_tuple_of(basesize_ratio_range, float)
          self.basesize_ratio_range = basesize_ratio_range
          # calculate anchor ratios and sizes
          min_ratio, max_ratio = basesize_ratio_range
          min_ratio = int(min_ratio * 100)
          max_ratio = int(max_ratio * 100)
          step = int(
              np.floor(max_ratio - min_ratio) / (self.num_levels - 2)
          )
          min_sizes = []
          max_sizes = []
          for ratio in range(int(min_ratio), int(max_ratio) + 1, step):
              min_sizes.append(int(self.input_size * ratio / 100))
              max_sizes.append(
                  int(self.input_size * (ratio + step) / 100)
              )
          if self.input_size == 300:
              if basesize_ratio_range[0] == 0.15:  # SSD300 COCO
                  min_sizes.insert(0, int(self.input_size * 7 / 100))
                  max_sizes.insert(0, int(self.input_size * 15 / 100))
              elif basesize_ratio_range[0] == 0.2:  # SSD300 VOC
                  min_sizes.insert(0, int(self.input_size * 10 / 100))
                  max_sizes.insert(0, int(self.input_size * 20 / 100))
              else:
                  raise ValueError(
                      "basesize_ratio_range[0] should be either 0.15"
                      "or 0.2 when input_size is 300, got "
                      f"{basesize_ratio_range[0]}."
                  )
          elif self.input_size == 512:
              if basesize_ratio_range[0] == 0.1:  # SSD512 COCO
                  min_sizes.insert(0, int(self.input_size * 4 / 100))
                  max_sizes.insert(0, int(self.input_size * 10 / 100))
              elif basesize_ratio_range[0] == 0.15:  # SSD512 VOC
                  min_sizes.insert(0, int(self.input_size * 7 / 100))
                  max_sizes.insert(0, int(self.input_size * 15 / 100))
              else:
                  raise ValueError(
                      "When not setting min_sizes and max_sizes,"
                      "basesize_ratio_range[0] should be either 0.1"
                      "or 0.15 when input_size is 512, got"
                      f" {basesize_ratio_range[0]}."
                  )
          else:
              raise ValueError(
                  "Only support 300 or 512 in SSDAnchorGenerator when "
                  "not setting min_sizes and max_sizes, "
                  f"got {self.input_size}."
              )
  
      assert len(min_sizes) == len(max_sizes) == len(strides)
  
      anchor_ratios = []
      anchor_scales = []
      for k in range(len(self.strides)):
          scales = [1.0, np.sqrt(max_sizes[k] / min_sizes[k])]
          anchor_ratio = [1.0]
          for r in ratios[k]:
              anchor_ratio += [1 / r, r]  # 4 or 6 ratio
          anchor_ratios.append(torch.Tensor(anchor_ratio))
          anchor_scales.append(torch.Tensor(scales))
  
      self.base_sizes = min_sizes
      self.scales = anchor_scales
      self.ratios = anchor_ratios
      self.scale_major = scale_major
      self.center_offset = 0
      self.base_anchors = self.gen_base_anchors()
      self.use_box_type = use_box_type
  
imports: import warnings
  from typing import List, Optional, Tuple, Union
  import numpy
  import torch
  from mmengine.utils import is_tuple_of
  from torch import Tensor
  from torch.nn.modules.utils import _pair
  from mmdet.registry import TASK_UTILS
  from mmdet.structures.bbox import HorizontalBoxes
label_desc: Use image node_id 1 to create a new SSDAnchorGenerator object from inherited base classes: AnchorGenerator with example: obj = SSDAnchorGenerator(strides, ratios, min_sizes, max_sizes, basesize_ratio_range, input_size, scale_major, use_box_type)