class_docstr: Path Aggregation Network used in YOLOX.
  
  Args:
      in_channels (List[int]): Number of input channels per scale.
      out_channels (int): Number of output channels (used at each scale)
      num_csp_blocks (int): Number of bottlenecks in CSPLayer. Default: 3
      use_depthwise (bool): Whether to depthwise separable convolution in
          blocks. Default: False
      upsample_cfg (dict): Config dict for interpolate layer.
          Default: `dict(scale_factor=2, mode='nearest')`
      conv_cfg (dict, optional): Config dict for convolution layer.
          Default: None, which means using conv2d.
      norm_cfg (dict): Config dict for normalization layer.
          Default: dict(type='BN')
      act_cfg (dict): Config dict for activation layer.
          Default: dict(type='Swish')
      init_cfg (dict or list[dict], optional): Initialization config dict.
          Default: None.
docstr: Args:
      inputs (tuple[Tensor]): input features.
  
  Returns:
      tuple[Tensor]: YOLOXPAFPN features.
docstr_tok: ["Args",":","inputs","(","tuple","[","Tensor","]",")",":","input","features",".","Returns",":","tuple","[","Tensor","]",":","YOLOXPAFPN","features","."]
code: def forward(self, inputs):
      """
      Args:
          inputs (tuple[Tensor]): input features.
  
      Returns:
          tuple[Tensor]: YOLOXPAFPN features.
      """
      assert len(inputs) == len(self.in_channels)
  
      # top-down path
      inner_outs = [inputs[-1]]
      for idx in range(len(self.in_channels) - 1, 0, -1):
          feat_heigh = inner_outs[0]
          feat_low = inputs[idx - 1]
          feat_heigh = self.reduce_layers[
              len(self.in_channels) - 1 - idx
          ](feat_heigh)
          inner_outs[0] = feat_heigh
  
          upsample_feat = self.upsample(feat_heigh)
  
          inner_out = self.top_down_blocks[
              len(self.in_channels) - 1 - idx
          ](torch.cat([upsample_feat, feat_low], 1))
          inner_outs.insert(0, inner_out)
  
      # bottom-up path
      outs = [inner_outs[0]]
      for idx in range(len(self.in_channels) - 1):
          feat_low = outs[-1]
          feat_height = inner_outs[idx + 1]
          downsample_feat = self.downsamples[idx](feat_low)
          out = self.bottom_up_blocks[idx](
              torch.cat([downsample_feat, feat_height], 1)
          )
          outs.append(out)
  
      # out convs
      for idx, conv in enumerate(self.out_convs):
          outs[idx] = conv(outs[idx])
  
      return tuple(outs)
  
file_path: mmdetection/mmdet/models/necks/yolox_pafpn.py
imports: import math
  import torch
  import torch.nn
  from mmcv.cnn import ConvModule, DepthwiseSeparableConvModule
  from mmengine.model import BaseModule
  from mmdet.registry import MODELS
  from ..layers import CSPLayer
label_desc: Use image node_id 2 for calling the YOLOXPAFPN obj's underlying member method code with example usage: obj.forward(inputs) and returns: tuple