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.
      basesize_ratio_range (tuple(float)): Ratio range of anchors.
      input_size (int): Size of feature map, 300 for SSD300,
          512 for SSD512.
      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.
code: def __init__(
      self,
      strides,
      ratios,
      basesize_ratio_range,
      input_size=300,
      scale_major=True,
  ):
      assert len(strides) == len(ratios)
      assert mmcv.is_tuple_of(basesize_ratio_range, float)
  
      self.strides = [_pair(stride) for stride in strides]
      self.input_size = input_size
      self.centers = [
          (stride[0] / 2.0, stride[1] / 2.0) for stride in self.strides
      ]
      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(
                  "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"
              f", got {self.input_size}."
          )
  
      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()
  
imports: import mmcv
  import numpy
  import torch
  from torch.nn.modules.utils import _pair
  from .builder import ANCHOR_GENERATORS
label_desc: Use image node_id 1 to create a new SSDAnchorGenerator object from inherited base classes: AnchorGenerator with example: obj = SSDAnchorGenerator(strides, ratios, basesize_ratio_range, input_size, scale_major)