class_docstr: Implementation of `Deformable DETR: Deformable Transformers for
  End-to-End Object Detection <https://arxiv.org/abs/2010.04159>`_
  
  Code is modified from the `official github repo
  <https://github.com/fundamentalvision/Deformable-DETR>`_.
  
  Args:
      decoder (:obj:`ConfigDict` or dict, optional): Config of the
          Transformer decoder. Defaults to None.
      bbox_head (:obj:`ConfigDict` or dict, optional): Config for the
          bounding box head module. Defaults to None.
      with_box_refine (bool, optional): Whether to refine the references
          in the decoder. Defaults to `False`.
      as_two_stage (bool, optional): Whether to generate the proposal
          from the outputs of encoder. Defaults to `False`.
      num_feature_levels (int, optional): Number of feature levels.
          Defaults to 4.
docstr: Process image features before feeding them to the transformer.
  
  The forward procedure of the transformer is defined as:
  'pre_transformer' -> 'encoder' -> 'pre_decoder' -> 'decoder'
  More details can be found at `TransformerDetector.forward_transformer`
  in `mmdet/detector/base_detr.py`.
  
  Args:
      mlvl_feats (tuple[Tensor]): Multi-level features that may have
          different resolutions, output from neck. Each feature has
          shape (bs, dim, h_lvl, w_lvl), where 'lvl' means 'layer'.
      batch_data_samples (list[:obj:`DetDataSample`], optional): The
          batch data samples. It usually includes information such
          as `gt_instance` or `gt_panoptic_seg` or `gt_sem_seg`.
          Defaults to None.
  
  Returns:
      tuple[dict]: The first dict contains the inputs of encoder and the
      second dict contains the inputs of decoder.
  
      - encoder_inputs_dict (dict): The keyword args dictionary of
        `self.forward_encoder()`, which includes 'feat', 'feat_mask',
        and 'feat_pos'.
      - decoder_inputs_dict (dict): The keyword args dictionary of
        `self.forward_decoder()`, which includes 'memory_mask'.
docstr_tok: ["Process","image","features","before","feeding","them","to","the","transformer",".","The","forward","procedure","of","the","transformer","is","defined","as",":","'pre_transformer","'","-",">","'encoder","'","-",">","'pre_decoder","'","-",">","'decoder'","More","details","can","be","found","at","`","TransformerDetector.forward_transformer","`","in","`","mmdet\/detector\/base_detr.py","`",".","Args",":","mlvl_feats","(","tuple","[","Tensor","]",")",":","Multi-level","features","that","may","have","different","resolutions",",","output","from","neck",".","Each","feature","has","shape","(","bs",",","dim",",","h_lvl",",","w_lvl",")",",","where","'lvl","'","means","'layer","'",".","batch_data_samples","(","list","[",":","obj",":","`","DetDataSample","`","]",",","optional",")",":","The","batch","data","samples",".","It","usually","includes","information","such","as","`","gt_instance","`","or","`","gt_panoptic_seg","`","or","`","gt_sem_seg","`",".","Defaults","to","None",".","Returns",":","tuple","[","dict","]",":","The","first","dict","contains","the","inputs","of","encoder","and","the","second","dict","contains","the","inputs","of","decoder",".","-","encoder_inputs_dict","(","dict",")",":","The","keyword","args","dictionary","of","`","self.forward_encoder","(",")","`",",","which","includes","'feat","'",",","'feat_mask","'",",","and","'feat_pos","'",".","-","decoder_inputs_dict","(","dict",")",":","The","keyword","args","dictionary","of","`","self.forward_decoder","(",")","`",",","which","includes","'memory_mask","'","."]
code: def pre_transformer(
      self,
      mlvl_feats: Tuple[Tensor],
      batch_data_samples: OptSampleList = None,
  ) -> Tuple[Dict]:
      """Process image features before feeding them to the transformer.
  
      The forward procedure of the transformer is defined as:
      'pre_transformer' -> 'encoder' -> 'pre_decoder' -> 'decoder'
      More details can be found at `TransformerDetector.forward_transformer`
      in `mmdet/detector/base_detr.py`.
  
      Args:
          mlvl_feats (tuple[Tensor]): Multi-level features that may have
              different resolutions, output from neck. Each feature has
              shape (bs, dim, h_lvl, w_lvl), where 'lvl' means 'layer'.
          batch_data_samples (list[:obj:`DetDataSample`], optional): The
              batch data samples. It usually includes information such
              as `gt_instance` or `gt_panoptic_seg` or `gt_sem_seg`.
              Defaults to None.
  
      Returns:
          tuple[dict]: The first dict contains the inputs of encoder and the
          second dict contains the inputs of decoder.
  
          - encoder_inputs_dict (dict): The keyword args dictionary of
            `self.forward_encoder()`, which includes 'feat', 'feat_mask',
            and 'feat_pos'.
          - decoder_inputs_dict (dict): The keyword args dictionary of
            `self.forward_decoder()`, which includes 'memory_mask'.
      """
      batch_size = mlvl_feats[0].size(0)
  
      # construct binary masks for the transformer.
      assert batch_data_samples is not None
      batch_input_shape = batch_data_samples[0].batch_input_shape
      input_img_h, input_img_w = batch_input_shape
      img_shape_list = [
          sample.img_shape for sample in batch_data_samples
      ]
      same_shape_flag = all(
          [
              s[0] == input_img_h and s[1] == input_img_w
              for s in img_shape_list
          ]
      )
      # support torch2onnx without feeding masks
      if torch.onnx.is_in_onnx_export() or same_shape_flag:
          mlvl_masks = []
          mlvl_pos_embeds = []
          for feat in mlvl_feats:
              mlvl_masks.append(None)
              mlvl_pos_embeds.append(
                  self.positional_encoding(None, input=feat)
              )
      else:
          masks = mlvl_feats[0].new_ones(
              (batch_size, input_img_h, input_img_w)
          )
          for img_id in range(batch_size):
              img_h, img_w = img_shape_list[img_id]
              masks[img_id, :img_h, :img_w] = 0
          # NOTE following the official DETR repo, non-zero
          # values representing ignored positions, while
          # zero values means valid positions.
  
          mlvl_masks = []
          mlvl_pos_embeds = []
          for feat in mlvl_feats:
              mlvl_masks.append(
                  F.interpolate(masks[None], size=feat.shape[-2:])
                  .to(torch.bool)
                  .squeeze(0)
              )
              mlvl_pos_embeds.append(
                  self.positional_encoding(mlvl_masks[-1])
              )
  
      feat_flatten = []
      lvl_pos_embed_flatten = []
      mask_flatten = []
      spatial_shapes = []
      for lvl, (feat, mask, pos_embed) in enumerate(
          zip(mlvl_feats, mlvl_masks, mlvl_pos_embeds)
      ):
          batch_size, c, h, w = feat.shape
          spatial_shape = torch._shape_as_tensor(feat)[2:].to(
              feat.device
          )
          # [bs, c, h_lvl, w_lvl] -> [bs, h_lvl*w_lvl, c]
          feat = feat.view(batch_size, c, -1).permute(0, 2, 1)
          pos_embed = pos_embed.view(batch_size, c, -1).permute(0, 2, 1)
          lvl_pos_embed = pos_embed + self.level_embed[lvl].view(
              1, 1, -1
          )
          # [bs, h_lvl, w_lvl] -> [bs, h_lvl*w_lvl]
          if mask is not None:
              mask = mask.flatten(1)
  
          feat_flatten.append(feat)
          lvl_pos_embed_flatten.append(lvl_pos_embed)
          mask_flatten.append(mask)
          spatial_shapes.append(spatial_shape)
  
      # (bs, num_feat_points, dim)
      feat_flatten = torch.cat(feat_flatten, 1)
      lvl_pos_embed_flatten = torch.cat(lvl_pos_embed_flatten, 1)
      # (bs, num_feat_points), where num_feat_points = sum_lvl(h_lvl*w_lvl)
      if mask_flatten[0] is not None:
          mask_flatten = torch.cat(mask_flatten, 1)
      else:
          mask_flatten = None
  
      # (num_level, 2)
      spatial_shapes = torch.cat(spatial_shapes).view(-1, 2)
      level_start_index = torch.cat(
          (
              spatial_shapes.new_zeros((1,)),  # (num_level)
              spatial_shapes.prod(1).cumsum(0)[:-1],
          )
      )
      if mlvl_masks[0] is not None:
          valid_ratios = torch.stack(  # (bs, num_level, 2)
              [self.get_valid_ratio(m) for m in mlvl_masks], 1
          )
      else:
          valid_ratios = mlvl_feats[0].new_ones(
              batch_size, len(mlvl_feats), 2
          )
  
      encoder_inputs_dict = dict(
          feat=feat_flatten,
          feat_mask=mask_flatten,
          feat_pos=lvl_pos_embed_flatten,
          spatial_shapes=spatial_shapes,
          level_start_index=level_start_index,
          valid_ratios=valid_ratios,
      )
      decoder_inputs_dict = dict(
          memory_mask=mask_flatten,
          spatial_shapes=spatial_shapes,
          level_start_index=level_start_index,
          valid_ratios=valid_ratios,
      )
      return encoder_inputs_dict, decoder_inputs_dict
  
imports: import math
  from typing import Dict, Tuple
  import torch
  import torch.nn.functional
  from mmcv.cnn.bricks.transformer import MultiScaleDeformableAttention
  from mmengine.model import xavier_init
  from torch import Tensor, nn
  from torch.nn.init import normal_
  from mmdet.registry import MODELS
  from mmdet.structures import OptSampleList
  from mmdet.utils import OptConfigType
  from ..layers import DeformableDetrTransformerDecoder, DeformableDetrTransformerEncoder, SinePositionalEncoding
  from .base_detr import DetectionTransformer
label_desc: Use image node_id 4 for calling the DeformableDETR obj's underlying member method code with example usage: obj.pre_transformer(mlvl_feats, batch_data_samples) and returns: encoder_inputs_dict,  decoder_inputs_dict