class_docstr: Focal and Global Knowledge Distillation for Detectors
  The code is reference from https://github.com/yzd-v/FGD/blob/master/mmdet/distillation/losses/fgd.py
  
  Args:
      student_channels (int): The number of channels in the student's FPN feature map. Default to 256.
      teacher_channels (int): The number of channels in the teacher's FPN feature map. Default to 256.
      normalize (bool): Whether to normalize the feature maps.
      temp (float, optional): The temperature coefficient. Defaults to 0.5.
      alpha_fgd (float, optional): The weight of fg_loss. Defaults to 0.001
      beta_fgd (float, optional): The weight of bg_loss. Defaults to 0.0005
      gamma_fgd (float, optional): The weight of mask_loss. Defaults to 0.001
      lambda_fgd (float, optional): The weight of relation_loss. Defaults to 0.000005
class_docstr_tok: ["Focal","and","Global","Knowledge","Distillation","for","Detectors","The","code","is","reference","from","https",":","\/\/github.com\/yzd-v\/FGD\/blob\/master\/mmdet\/distillation\/losses\/fgd.py","Args",":","student_channels","(","int",")",":","The","number","of","channels","in","the","student","'s","FPN","feature","map",".","Default","to","256.","teacher_channels","(","int",")",":","The","number","of","channels","in","the","teacher","'s","FPN","feature","map",".","Default","to","256.","normalize","(","bool",")",":","Whether","to","normalize","the","feature","maps",".","temp","(","float",",","optional",")",":","The","temperature","coefficient",".","Defaults","to","0.5.","alpha_fgd","(","float",",","optional",")",":","The","weight","of","fg_loss",".","Defaults","to","0.001","beta_fgd","(","float",",","optional",")",":","The","weight","of","bg_loss",".","Defaults","to","0.0005","gamma_fgd","(","float",",","optional",")",":","The","weight","of","mask_loss",".","Defaults","to","0.001","lambda_fgd","(","float",",","optional",")",":","The","weight","of","relation_loss",".","Defaults","to","0.000005"]
code: def forward(self, stu_feature, tea_feature, inputs):
      assert stu_feature.shape[-2:] == stu_feature.shape[-2:]
      assert "gt_bbox" in inputs.keys() and "im_shape" in inputs.keys()
      gt_bboxes = inputs["gt_bbox"]
      ins_shape = [
          inputs["im_shape"][i]
          for i in range(inputs["im_shape"].shape[0])
      ]
      index_gt = []
      for i in range(len(gt_bboxes)):
          if gt_bboxes[i].size > 2:
              index_gt.append(i)
      # only distill feature with labeled GTbox
      if len(index_gt) != len(gt_bboxes):
          index_gt_t = paddle.to_tensor(index_gt)
          stu_feature = paddle.index_select(stu_feature, index_gt_t)
          tea_feature = paddle.index_select(tea_feature, index_gt_t)
  
          ins_shape = [ins_shape[c] for c in index_gt]
          gt_bboxes = [gt_bboxes[c] for c in index_gt]
          assert len(gt_bboxes) == tea_feature.shape[0]
  
      if self.align is not None:
          stu_feature = self.align(stu_feature)
  
      if self.normalize:
          stu_feature = feature_norm(stu_feature)
          tea_feature = feature_norm(tea_feature)
  
      tea_spatial_att, tea_channel_att = self.spatial_channel_attention(
          tea_feature, self.temp
      )
      stu_spatial_att, stu_channel_att = self.spatial_channel_attention(
          stu_feature, self.temp
      )
  
      mask_fg = paddle.zeros(tea_spatial_att.shape)
      mask_bg = paddle.ones_like(tea_spatial_att)
      one_tmp = paddle.ones([*tea_spatial_att.shape[1:]])
      zero_tmp = paddle.zeros([*tea_spatial_att.shape[1:]])
      mask_fg.stop_gradient = True
      mask_bg.stop_gradient = True
      one_tmp.stop_gradient = True
      zero_tmp.stop_gradient = True
  
      wmin, wmax, hmin, hmax = [], [], [], []
  
      if len(gt_bboxes) == 0:
          loss = self.relation_loss(stu_feature, tea_feature)
          return self.lambda_fgd * loss
  
      N, _, H, W = stu_feature.shape
      for i in range(N):
          tmp_box = paddle.ones_like(gt_bboxes[i])
          tmp_box.stop_gradient = True
          tmp_box[:, 0] = gt_bboxes[i][:, 0] / ins_shape[i][1] * W
          tmp_box[:, 2] = gt_bboxes[i][:, 2] / ins_shape[i][1] * W
          tmp_box[:, 1] = gt_bboxes[i][:, 1] / ins_shape[i][0] * H
          tmp_box[:, 3] = gt_bboxes[i][:, 3] / ins_shape[i][0] * H
  
          zero = paddle.zeros_like(tmp_box[:, 0], dtype="int32")
          ones = paddle.ones_like(tmp_box[:, 2], dtype="int32")
          zero.stop_gradient = True
          ones.stop_gradient = True
          wmin.append(
              paddle.cast(paddle.floor(tmp_box[:, 0]), "int32").maximum(
                  zero
              )
          )
          wmax.append(paddle.cast(paddle.ceil(tmp_box[:, 2]), "int32"))
          hmin.append(
              paddle.cast(paddle.floor(tmp_box[:, 1]), "int32").maximum(
                  zero
              )
          )
          hmax.append(paddle.cast(paddle.ceil(tmp_box[:, 3]), "int32"))
  
          area_recip = (
              1.0
              / (
                  hmax[i].reshape([1, -1])
                  + 1
                  - hmin[i].reshape([1, -1])
              )
              / (
                  wmax[i].reshape([1, -1])
                  + 1
                  - wmin[i].reshape([1, -1])
              )
          )
  
          for j in range(len(gt_bboxes[i])):
              if gt_bboxes[i][j].sum() > 0:
                  mask_fg[i] = self.mask_value(
                      mask_fg[i],
                      hmin[i][j],
                      hmax[i][j] + 1,
                      wmin[i][j],
                      wmax[i][j] + 1,
                      area_recip[0][j],
                  )
  
          mask_bg[i] = paddle.where(
              mask_fg[i] > zero_tmp, zero_tmp, one_tmp
          )
  
          if paddle.sum(mask_bg[i]):
              mask_bg[i] /= paddle.sum(mask_bg[i])
  
      fg_loss, bg_loss = self.feature_loss(
          stu_feature,
          tea_feature,
          mask_fg,
          mask_bg,
          tea_channel_att,
          tea_spatial_att,
      )
      mask_loss = self.mask_loss(
          stu_channel_att,
          tea_channel_att,
          stu_spatial_att,
          tea_spatial_att,
      )
      rela_loss = self.relation_loss(stu_feature, tea_feature)
      loss = (
          self.alpha_fgd * fg_loss
          + self.beta_fgd * bg_loss
          + self.gamma_fgd * mask_loss
          + self.lambda_fgd * rela_loss
      )
      return loss * self.loss_weight
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import math
  import paddle
  import paddle.nn
  import paddle.nn.functional
  from paddle import ParamAttr
  from ppdet.core.workspace import register
  from ppdet.modeling import ops
  from ppdet.modeling.losses.iou_loss import GIoULoss
  from ppdet.utils.logger import setup_logger
label_desc: Use image node_id 8 for calling the FGDFeatureLoss obj's underlying member method code with example usage: obj.forward(stu_feature, tea_feature, inputs) and returns: unknown, unknown