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 get_loss(self, head_outs, inputs):
      (
          fam_cls_list,
          fam_reg_list,
          odm_cls_list,
          odm_reg_list,
          num_anchors_list,
          base_anchors_list,
          refine_anchors_list,
      ) = head_outs
  
      # compute loss
      fam_cls_loss_lst = []
      fam_reg_loss_lst = []
      odm_cls_loss_lst = []
      odm_reg_loss_lst = []
  
      batch = len(inputs["gt_rbox"])
      for i in range(batch):
          # data_format: (xc, yc, w, h, theta)
          gt_mask = inputs["pad_gt_mask"][i, :, 0]
          gt_idx = paddle.nonzero(gt_mask).squeeze(-1)
          gt_bboxes = paddle.gather(
              inputs["gt_rbox"][i], gt_idx
          ).numpy()
          gt_labels = paddle.gather(
              inputs["gt_class"][i], gt_idx
          ).numpy()
          is_crowd = paddle.gather(
              inputs["is_crowd"][i], gt_idx
          ).numpy()
          gt_labels = gt_labels + 1
  
          anchors_per_image = np.concatenate(base_anchors_list)
  
          fam_cls_per_image = [t[i] for t in fam_cls_list]
          fam_reg_per_image = [t[i] for t in fam_reg_list]
          odm_cls_per_image = [t[i] for t in odm_cls_list]
          odm_reg_per_image = [t[i] for t in odm_reg_list]
          im_s2anet_head_out = (
              fam_cls_per_image,
              fam_reg_per_image,
              odm_cls_per_image,
              odm_reg_per_image,
              num_anchors_list,
          )
          # FAM
          im_fam_target = self.anchor_assign(
              anchors_per_image, gt_bboxes, gt_labels, is_crowd
          )
          if im_fam_target is not None:
              im_fam_cls_loss, im_fam_reg_loss = self.get_fam_loss(
                  im_fam_target, im_s2anet_head_out, self.reg_loss_type
              )
              fam_cls_loss_lst.append(im_fam_cls_loss)
              fam_reg_loss_lst.append(im_fam_reg_loss)
  
          # ODM
          refine_anchors_per_image = [t[i] for t in refine_anchors_list]
          refine_anchors_per_image = paddle.concat(
              refine_anchors_per_image
          ).numpy()
          im_odm_target = self.anchor_assign(
              refine_anchors_per_image, gt_bboxes, gt_labels, is_crowd
          )
  
          if im_odm_target is not None:
              im_odm_cls_loss, im_odm_reg_loss = self.get_odm_loss(
                  im_odm_target, im_s2anet_head_out, self.reg_loss_type
              )
              odm_cls_loss_lst.append(im_odm_cls_loss)
              odm_reg_loss_lst.append(im_odm_reg_loss)
  
      fam_cls_loss = paddle.add_n(fam_cls_loss_lst) / batch
      fam_reg_loss = paddle.add_n(fam_reg_loss_lst) / batch
      odm_cls_loss = paddle.add_n(odm_cls_loss_lst) / batch
      odm_reg_loss = paddle.add_n(odm_reg_loss_lst) / batch
      loss = fam_cls_loss + fam_reg_loss + odm_cls_loss + odm_reg_loss
  
      return {
          "loss": loss,
          "fam_cls_loss": fam_cls_loss,
          "fam_reg_loss": fam_reg_loss,
          "odm_cls_loss": odm_cls_loss,
          "odm_reg_loss": odm_reg_loss,
      }
  
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 9 for calling the S2ANetHead obj's underlying member method code with example usage: obj.get_loss(head_outs, inputs) and returns: dict