class_docstr: More general bbox head, with shared conv and fc layers and two optional
  separated branches.
  
  .. code-block:: none
  
                                  /-> cls convs -> cls fcs -> cls
      shared convs -> shared fcs
                                  \-> reg convs -> reg fcs -> reg
code: def __init__(
      self,
      num_shared_convs=0,
      num_shared_fcs=0,
      num_cls_convs=0,
      num_cls_fcs=0,
      num_reg_convs=0,
      num_reg_fcs=0,
      conv_out_channels=256,
      fc_out_channels=1024,
      conv_cfg=None,
      norm_cfg=None,
      *args,
      **kwargs,
  ):
      super(ConvFCBBoxHead, self).__init__(*args, **kwargs)
      assert (
          num_shared_convs
          + num_shared_fcs
          + num_cls_convs
          + num_cls_fcs
          + num_reg_convs
          + num_reg_fcs
          > 0
      )
      if num_cls_convs > 0 or num_reg_convs > 0:
          assert num_shared_fcs == 0
      if not self.with_cls:
          assert num_cls_convs == 0 and num_cls_fcs == 0
      if not self.with_reg:
          assert num_reg_convs == 0 and num_reg_fcs == 0
      self.num_shared_convs = num_shared_convs
      self.num_shared_fcs = num_shared_fcs
      self.num_cls_convs = num_cls_convs
      self.num_cls_fcs = num_cls_fcs
      self.num_reg_convs = num_reg_convs
      self.num_reg_fcs = num_reg_fcs
      self.conv_out_channels = conv_out_channels
      self.fc_out_channels = fc_out_channels
      self.conv_cfg = conv_cfg
      self.norm_cfg = norm_cfg
  
      # add shared convs and fcs
      (
          self.shared_convs,
          self.shared_fcs,
          last_layer_dim,
      ) = self._add_conv_fc_branch(
          self.num_shared_convs,
          self.num_shared_fcs,
          self.in_channels,
          True,
      )
      self.shared_out_channels = last_layer_dim
  
      # add cls specific branch
      (
          self.cls_convs,
          self.cls_fcs,
          self.cls_last_dim,
      ) = self._add_conv_fc_branch(
          self.num_cls_convs, self.num_cls_fcs, self.shared_out_channels
      )
  
      # add reg specific branch
      (
          self.reg_convs,
          self.reg_fcs,
          self.reg_last_dim,
      ) = self._add_conv_fc_branch(
          self.num_reg_convs, self.num_reg_fcs, self.shared_out_channels
      )
  
      if self.num_shared_fcs == 0 and not self.with_avg_pool:
          if self.num_cls_fcs == 0:
              self.cls_last_dim *= self.roi_feat_area
          if self.num_reg_fcs == 0:
              self.reg_last_dim *= self.roi_feat_area
  
      self.relu = nn.ReLU(inplace=True)
      # reconstruct fc_cls and fc_reg since input channels are changed
      if self.with_cls:
          self.fc_cls = nn.Linear(
              self.cls_last_dim, self.num_classes + 1
          )
      if self.with_reg:
          out_dim_reg = (
              4 if self.reg_class_agnostic else 4 * self.num_classes
          )
          self.fc_reg = nn.Linear(self.reg_last_dim, out_dim_reg)
  
file_path: insightface/detection/scrfd/mmdet/models/roi_heads/bbox_heads/convfc_bbox_head.py
imports: import torch.nn
  from mmcv.cnn import ConvModule
  from mmdet.models.builder import HEADS
  from .bbox_head import BBoxHead
label_desc: Use image node_id 1 to create a new ConvFCBBoxHead object from inherited base classes: BBoxHead with example: obj = ConvFCBBoxHead(num_shared_convs, num_shared_fcs, num_cls_convs, num_cls_fcs, num_reg_convs, num_reg_fcs, conv_out_channels, fc_out_channels, conv_cfg, norm_cfg)