class_docstr: S2Anet head
  Args:
      stacked_convs (int): number of stacked_convs
      feat_in (int): input channels of feat
      feat_out (int): output channels of feat
      num_classes (int): num_classes
      anchor_strides (list): stride of anchors
      anchor_scales (list): scale of anchors
      anchor_ratios (list): ratios of anchors
      target_means (list): target_means
      target_stds (list): target_stds
      align_conv_type (str): align_conv_type ['Conv', 'AlignConv']
      align_conv_size (int): kernel size of align_conv
      use_sigmoid_cls (bool): use sigmoid_cls or not
      reg_loss_weight (list): loss weight for regression
class_docstr_tok: ["S2Anet","head","Args",":","stacked_convs","(","int",")",":","number","of","stacked_convs","feat_in","(","int",")",":","input","channels","of","feat","feat_out","(","int",")",":","output","channels","of","feat","num_classes","(","int",")",":","num_classes","anchor_strides","(","list",")",":","stride","of","anchors","anchor_scales","(","list",")",":","scale","of","anchors","anchor_ratios","(","list",")",":","ratios","of","anchors","target_means","(","list",")",":","target_means","target_stds","(","list",")",":","target_stds","align_conv_type","(","str",")",":","align_conv_type","[","'Conv","'",",","'AlignConv","'","]","align_conv_size","(","int",")",":","kernel","size","of","align_conv","use_sigmoid_cls","(","bool",")",":","use","sigmoid_cls","or","not","reg_loss_weight","(","list",")",":","loss","weight","for","regression"]
code: def __init__(
      self,
      stacked_convs=2,
      feat_in=256,
      feat_out=256,
      num_classes=15,
      anchor_strides=[8, 16, 32, 64, 128],
      anchor_scales=[4],
      anchor_ratios=[1.0],
      target_means=0.0,
      target_stds=1.0,
      align_conv_type="AlignConv",
      align_conv_size=3,
      use_sigmoid_cls=True,
      anchor_assign=_get_class_default_kwargs(RBoxAssigner),
      reg_loss_weight=[1.0, 1.0, 1.0, 1.0, 1.1],
      cls_loss_weight=[1.1, 1.05],
      reg_loss_type="l1",
      nms_pre=2000,
      nms="MultiClassNMS",
  ):
      super(S2ANetHead, self).__init__()
      self.stacked_convs = stacked_convs
      self.feat_in = feat_in
      self.feat_out = feat_out
      self.anchor_list = None
      self.anchor_scales = anchor_scales
      self.anchor_ratios = anchor_ratios
      self.anchor_strides = anchor_strides
      self.anchor_strides = paddle.to_tensor(anchor_strides)
      self.anchor_base_sizes = list(anchor_strides)
      self.means = paddle.ones(shape=[5]) * target_means
      self.stds = paddle.ones(shape=[5]) * target_stds
      assert align_conv_type in ["AlignConv", "Conv", "DCN"]
      self.align_conv_type = align_conv_type
      self.align_conv_size = align_conv_size
  
      self.use_sigmoid_cls = use_sigmoid_cls
      self.cls_out_channels = (
          num_classes if self.use_sigmoid_cls else num_classes + 1
      )
      self.sampling = False
      self.anchor_assign = anchor_assign
      self.reg_loss_weight = reg_loss_weight
      self.cls_loss_weight = cls_loss_weight
      self.alpha = 1.0
      self.beta = 1.0
      self.reg_loss_type = reg_loss_type
      self.nms_pre = nms_pre
      self.nms = nms
      self.fake_bbox = paddle.to_tensor(
          np.array(
              [[-1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]],
              dtype="float32",
          )
      )
      self.fake_bbox_num = paddle.to_tensor(
          np.array([1], dtype="int32")
      )
  
      # anchor
      self.anchor_generators = []
      for anchor_base in self.anchor_base_sizes:
          self.anchor_generators.append(
              S2ANetAnchorGenerator(
                  anchor_base, anchor_scales, anchor_ratios
              )
          )
  
      self.anchor_generators = nn.LayerList(self.anchor_generators)
      self.fam_cls_convs = nn.Sequential()
      self.fam_reg_convs = nn.Sequential()
  
      for i in range(self.stacked_convs):
          chan_in = self.feat_in if i == 0 else self.feat_out
  
          self.fam_cls_convs.add_sublayer(
              "fam_cls_conv_{}".format(i),
              nn.Conv2D(
                  in_channels=chan_in,
                  out_channels=self.feat_out,
                  kernel_size=3,
                  padding=1,
                  weight_attr=ParamAttr(initializer=Normal(0.0, 0.01)),
                  bias_attr=ParamAttr(initializer=Constant(0)),
              ),
          )
  
          self.fam_cls_convs.add_sublayer(
              "fam_cls_conv_{}_act".format(i), nn.ReLU()
          )
  
          self.fam_reg_convs.add_sublayer(
              "fam_reg_conv_{}".format(i),
              nn.Conv2D(
                  in_channels=chan_in,
                  out_channels=self.feat_out,
                  kernel_size=3,
                  padding=1,
                  weight_attr=ParamAttr(initializer=Normal(0.0, 0.01)),
                  bias_attr=ParamAttr(initializer=Constant(0)),
              ),
          )
  
          self.fam_reg_convs.add_sublayer(
              "fam_reg_conv_{}_act".format(i), nn.ReLU()
          )
  
      self.fam_reg = nn.Conv2D(
          self.feat_out,
          5,
          1,
          weight_attr=ParamAttr(initializer=Normal(0.0, 0.01)),
          bias_attr=ParamAttr(initializer=Constant(0)),
      )
      prior_prob = 0.01
      bias_init = float(-np.log((1 - prior_prob) / prior_prob))
      self.fam_cls = nn.Conv2D(
          self.feat_out,
          self.cls_out_channels,
          1,
          weight_attr=ParamAttr(initializer=Normal(0.0, 0.01)),
          bias_attr=ParamAttr(initializer=Constant(bias_init)),
      )
  
      if self.align_conv_type == "AlignConv":
          self.align_conv = AlignConv(
              self.feat_out, self.feat_out, self.align_conv_size
          )
      elif self.align_conv_type == "Conv":
          self.align_conv = nn.Conv2D(
              self.feat_out,
              self.feat_out,
              self.align_conv_size,
              padding=(self.align_conv_size - 1) // 2,
              bias_attr=ParamAttr(initializer=Constant(0)),
          )
  
      elif self.align_conv_type == "DCN":
          self.align_conv_offset = nn.Conv2D(
              self.feat_out,
              2 * self.align_conv_size**2,
              1,
              weight_attr=ParamAttr(initializer=Normal(0.0, 0.01)),
              bias_attr=ParamAttr(initializer=Constant(0)),
          )
  
          self.align_conv = paddle.vision.ops.DeformConv2D(
              self.feat_out,
              self.feat_out,
              self.align_conv_size,
              padding=(self.align_conv_size - 1) // 2,
              weight_attr=ParamAttr(initializer=Normal(0.0, 0.01)),
              bias_attr=False,
          )
  
      self.or_conv = nn.Conv2D(
          self.feat_out,
          self.feat_out,
          kernel_size=3,
          padding=1,
          weight_attr=ParamAttr(initializer=Normal(0.0, 0.01)),
          bias_attr=ParamAttr(initializer=Constant(0)),
      )
  
      # ODM
      self.odm_cls_convs = nn.Sequential()
      self.odm_reg_convs = nn.Sequential()
  
      for i in range(self.stacked_convs):
          ch_in = self.feat_out
          # ch_in = int(self.feat_out / 8) if i == 0 else self.feat_out
  
          self.odm_cls_convs.add_sublayer(
              "odm_cls_conv_{}".format(i),
              nn.Conv2D(
                  in_channels=ch_in,
                  out_channels=self.feat_out,
                  kernel_size=3,
                  stride=1,
                  padding=1,
                  weight_attr=ParamAttr(initializer=Normal(0.0, 0.01)),
                  bias_attr=ParamAttr(initializer=Constant(0)),
              ),
          )
  
          self.odm_cls_convs.add_sublayer(
              "odm_cls_conv_{}_act".format(i), nn.ReLU()
          )
  
          self.odm_reg_convs.add_sublayer(
              "odm_reg_conv_{}".format(i),
              nn.Conv2D(
                  in_channels=self.feat_out,
                  out_channels=self.feat_out,
                  kernel_size=3,
                  stride=1,
                  padding=1,
                  weight_attr=ParamAttr(initializer=Normal(0.0, 0.01)),
                  bias_attr=ParamAttr(initializer=Constant(0)),
              ),
          )
  
          self.odm_reg_convs.add_sublayer(
              "odm_reg_conv_{}_act".format(i), nn.ReLU()
          )
  
      self.odm_cls = nn.Conv2D(
          self.feat_out,
          self.cls_out_channels,
          3,
          padding=1,
          weight_attr=ParamAttr(initializer=Normal(0.0, 0.01)),
          bias_attr=ParamAttr(initializer=Constant(bias_init)),
      )
      self.odm_reg = nn.Conv2D(
          self.feat_out,
          5,
          3,
          padding=1,
          weight_attr=ParamAttr(initializer=Normal(0.0, 0.01)),
          bias_attr=ParamAttr(initializer=Constant(0)),
      )
  
imports: import paddle
  from paddle import ParamAttr
  import paddle.nn
  import paddle.nn.functional
  from paddle.nn.initializer import Normal, Constant
  from ppdet.core.workspace import register
  from ppdet.modeling.proposal_generator.target_layer import RBoxAssigner
  from ppdet.modeling.proposal_generator.anchor_generator import S2ANetAnchorGenerator
  from ppdet.modeling.layers import AlignConv
  from ..cls_utils import _get_class_default_kwargs
  import numpy
label_desc: Use image node_id 1 to create a new S2ANetHead object from inherited base classes: nn with example: obj = S2ANetHead(stacked_convs, feat_in, feat_out, num_classes, anchor_strides, anchor_scales, anchor_ratios, target_means, target_stds, align_conv_type, align_conv_size, use_sigmoid_cls, anchor_assign, reg_loss_weight, cls_loss_weight, reg_loss_type, nms_pre, nms)