docstr: :param bboxes: (N, nr_boxes, 4)
  :param pro_features: (N, nr_boxes, d_model)
docstr_tok: [":","param","bboxes",":","(","N",",","nr_boxes",",","4",")",":","param","pro_features",":","(","N",",","nr_boxes",",","d_model",")"]
code: def forward(self, features, bboxes, pro_features, pooler):
      """
      :param bboxes: (N, nr_boxes, 4)
      :param pro_features: (N, nr_boxes, d_model)
      """
  
      N, nr_boxes = bboxes.shape[:2]
  
      proposal_boxes = list()
      for b in range(N):
          proposal_boxes.append(bboxes[b])
      roi_num = paddle.full([N], nr_boxes).astype("int32")
  
      roi_features = pooler(features, proposal_boxes, roi_num)
      roi_features = roi_features.reshape(
          [N * nr_boxes, self.d_model, -1]
      ).transpose(perm=[2, 0, 1])
  
      # self_att.
      pro_features = pro_features.reshape([N, nr_boxes, self.d_model])
      pro_features2 = self.self_attn(
          pro_features, pro_features, value=pro_features
      )
      pro_features = pro_features.transpose(
          perm=[1, 0, 2]
      ) + self.dropout1(pro_features2.transpose(perm=[1, 0, 2]))
      pro_features = self.norm1(pro_features)
  
      # inst_interact.
      pro_features = (
          pro_features.reshape([nr_boxes, N, self.d_model])
          .transpose(perm=[1, 0, 2])
          .reshape([1, N * nr_boxes, self.d_model])
      )
      pro_features2 = self.inst_interact(pro_features, roi_features)
      pro_features = pro_features + self.dropout2(pro_features2)
      obj_features = self.norm2(pro_features)
  
      # obj_feature.
      obj_features2 = self.linear2(
          self.dropout(self.activation(self.linear1(obj_features)))
      )
      obj_features = obj_features + self.dropout3(obj_features2)
      obj_features = self.norm3(obj_features)
  
      fc_feature = obj_features.transpose(perm=[1, 0, 2]).reshape(
          [N * nr_boxes, -1]
      )
      cls_feature = fc_feature.clone()
      reg_feature = fc_feature.clone()
      for cls_layer in self.cls_module:
          cls_feature = cls_layer(cls_feature)
      for reg_layer in self.reg_module:
          reg_feature = reg_layer(reg_feature)
      class_logits = self.class_logits(cls_feature)
      bboxes_deltas = self.bboxes_delta(reg_feature)
      pred_bboxes = delta2bbox(
          bboxes_deltas, bboxes.reshape([-1, 4]), self.bbox_weights
      )
  
      return (
          class_logits.reshape([N, nr_boxes, -1]),
          pred_bboxes.reshape([N, nr_boxes, -1]),
          obj_features,
      )
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import math
  import copy
  import paddle
  import paddle.nn
  from ppdet.core.workspace import register
  from ppdet.modeling.heads.roi_extractor import RoIAlign
  from ppdet.modeling.bbox_utils import delta2bbox
  from ..None import initializer
label_desc: Use image node_id 2 for calling the RCNNHead obj's underlying member method code with example usage: obj.forward(features, bboxes, pro_features, pooler) and returns: class_logits,  pred_bboxes,  obj_features