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 forward(self, feats, targets=None):
      fam_reg_list, fam_cls_list = [], []
      odm_reg_list, odm_cls_list = [], []
      num_anchors_list, base_anchors_list, refine_anchors_list = (
          [],
          [],
          [],
      )
  
      for i, feat in enumerate(feats):
          # get shape
          B = feat.shape[0]
          H, W = paddle.shape(feat)[2], paddle.shape(feat)[3]
  
          NA = H * W
          num_anchors_list.append(NA)
  
          fam_cls_feat = self.fam_cls_convs(feat)
          fam_cls = self.fam_cls(fam_cls_feat)
          # [N, CLS, H, W] --> [N, H, W, CLS]
          fam_cls = fam_cls.transpose([0, 2, 3, 1]).reshape(
              [B, NA, self.cls_out_channels]
          )
          fam_cls_list.append(fam_cls)
  
          fam_reg_feat = self.fam_reg_convs(feat)
          fam_reg = self.fam_reg(fam_reg_feat)
          # [N, 5, H, W] --> [N, H, W, 5]
          fam_reg = fam_reg.transpose([0, 2, 3, 1]).reshape([B, NA, 5])
          fam_reg_list.append(fam_reg)
  
          # prepare anchor
          init_anchors = self.anchor_generators[i](
              (H, W), self.anchor_strides[i]
          )
          init_anchors = init_anchors.reshape([1, NA, 5])
          base_anchors_list.append(init_anchors.squeeze(0))
  
          if self.training:
              refine_anchor = self.bbox_decode(
                  fam_reg.detach(), init_anchors
              )
          else:
              refine_anchor = self.bbox_decode(fam_reg, init_anchors)
  
          refine_anchors_list.append(refine_anchor)
  
          if self.align_conv_type == "AlignConv":
              align_feat = self.align_conv(
                  feat,
                  refine_anchor.clone(),
                  (H, W),
                  self.anchor_strides[i],
              )
          elif self.align_conv_type == "DCN":
              align_offset = self.align_conv_offset(feat)
              align_feat = self.align_conv(feat, align_offset)
          elif self.align_conv_type == "Conv":
              align_feat = self.align_conv(feat)
  
          or_feat = self.or_conv(align_feat)
          odm_reg_feat = or_feat
          odm_cls_feat = or_feat
  
          odm_reg_feat = self.odm_reg_convs(odm_reg_feat)
          odm_cls_feat = self.odm_cls_convs(odm_cls_feat)
  
          odm_cls = self.odm_cls(odm_cls_feat)
          # [N, CLS, H, W] --> [N, H, W, CLS]
          odm_cls = odm_cls.transpose([0, 2, 3, 1]).reshape(
              [B, NA, self.cls_out_channels]
          )
          odm_cls_list.append(odm_cls)
  
          odm_reg = self.odm_reg(odm_reg_feat)
          # [N, 5, H, W] --> [N, H, W, 5]
          odm_reg = odm_reg.transpose([0, 2, 3, 1]).reshape([B, NA, 5])
          odm_reg_list.append(odm_reg)
  
      if self.training:
          return self.get_loss(
              [
                  fam_cls_list,
                  fam_reg_list,
                  odm_cls_list,
                  odm_reg_list,
                  num_anchors_list,
                  base_anchors_list,
                  refine_anchors_list,
              ],
              targets,
          )
      else:
          odm_bboxes_list = []
          for odm_reg, refine_anchor in zip(
              odm_reg_list, refine_anchors_list
          ):
              odm_bboxes = self.bbox_decode(odm_reg, refine_anchor)
              odm_bboxes_list.append(odm_bboxes)
          return [odm_bboxes_list, odm_cls_list]
  
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 2 for calling the S2ANetHead obj's underlying member method code with example usage: obj.forward(feats, targets) and returns: self, list