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: Generate proposals from encoded memory. The function will only be
  used when `as_two_stage` is `True`.
  
  Args:
      memory (Tensor): The output embeddings of the Transformer encoder,
          has shape (bs, num_feat_points, dim).
      memory_mask (Tensor): ByteTensor, the padding mask of the memory,
          has shape (bs, num_feat_points).
      spatial_shapes (Tensor): Spatial shapes of features in all levels,
          has shape (num_levels, 2), last dimension represents (h, w).
  
  Returns:
      tuple: A tuple of transformed memory and proposals.
  
      - output_memory (Tensor): The transformed memory for obtaining
        top-k proposals, has shape (bs, num_feat_points, dim).
      - output_proposals (Tensor): The inverse-normalized proposal, has
        shape (batch_size, num_keys, 4) with the last dimension arranged
        as (cx, cy, w, h).
docstr_tok: ["Generate","proposals","from","encoded","memory",".","The","function","will","only","be","used","when","`","as_two_stage","`","is","`","True","`",".","Args",":","memory","(","Tensor",")",":","The","output","embeddings","of","the","Transformer","encoder",",","has","shape","(","bs",",","num_feat_points",",","dim",")",".","memory_mask","(","Tensor",")",":","ByteTensor",",","the","padding","mask","of","the","memory",",","has","shape","(","bs",",","num_feat_points",")",".","spatial_shapes","(","Tensor",")",":","Spatial","shapes","of","features","in","all","levels",",","has","shape","(","num_levels",",","2",")",",","last","dimension","represents","(","h",",","w",")",".","Returns",":","tuple",":","A","tuple","of","transformed","memory","and","proposals",".","-","output_memory","(","Tensor",")",":","The","transformed","memory","for","obtaining","top-k","proposals",",","has","shape","(","bs",",","num_feat_points",",","dim",")",".","-","output_proposals","(","Tensor",")",":","The","inverse-normalized","proposal",",","has","shape","(","batch_size",",","num_keys",",","4",")","with","the","last","dimension","arranged","as","(","cx",",","cy",",","w",",","h",")","."]
code: def gen_encoder_output_proposals(
      self, memory: Tensor, memory_mask: Tensor, spatial_shapes: Tensor
  ) -> Tuple[Tensor, Tensor]:
      """Generate proposals from encoded memory. The function will only be
      used when `as_two_stage` is `True`.
  
      Args:
          memory (Tensor): The output embeddings of the Transformer encoder,
              has shape (bs, num_feat_points, dim).
          memory_mask (Tensor): ByteTensor, the padding mask of the memory,
              has shape (bs, num_feat_points).
          spatial_shapes (Tensor): Spatial shapes of features in all levels,
              has shape (num_levels, 2), last dimension represents (h, w).
  
      Returns:
          tuple: A tuple of transformed memory and proposals.
  
          - output_memory (Tensor): The transformed memory for obtaining
            top-k proposals, has shape (bs, num_feat_points, dim).
          - output_proposals (Tensor): The inverse-normalized proposal, has
            shape (batch_size, num_keys, 4) with the last dimension arranged
            as (cx, cy, w, h).
      """
  
      bs = memory.size(0)
      proposals = []
      _cur = 0  # start index in the sequence of the current level
      for lvl, HW in enumerate(spatial_shapes):
          H, W = HW
  
          if memory_mask is not None:
              mask_flatten_ = memory_mask[
                  :, _cur : (_cur + H * W)
              ].view(bs, H, W, 1)
              valid_H = torch.sum(
                  ~mask_flatten_[:, :, 0, 0], 1
              ).unsqueeze(-1)
              valid_W = torch.sum(
                  ~mask_flatten_[:, 0, :, 0], 1
              ).unsqueeze(-1)
              scale = torch.cat([valid_W, valid_H], 1).view(bs, 1, 1, 2)
          else:
              if not isinstance(HW, torch.Tensor):
                  HW = memory.new_tensor(HW)
              scale = HW.unsqueeze(0).flip(dims=[0, 1]).view(1, 1, 1, 2)
          grid_y, grid_x = torch.meshgrid(
              torch.linspace(
                  0, H - 1, H, dtype=torch.float32, device=memory.device
              ),
              torch.linspace(
                  0, W - 1, W, dtype=torch.float32, device=memory.device
              ),
          )
          grid = torch.cat(
              [grid_x.unsqueeze(-1), grid_y.unsqueeze(-1)], -1
          )
          grid = (
              grid.unsqueeze(0).expand(bs, -1, -1, -1) + 0.5
          ) / scale
          wh = torch.ones_like(grid) * 0.05 * (2.0**lvl)
          proposal = torch.cat((grid, wh), -1).view(bs, -1, 4)
          proposals.append(proposal)
          _cur += H * W
      output_proposals = torch.cat(proposals, 1)
      # do not use `all` to make it exportable to onnx
      output_proposals_valid = (
          (output_proposals > 0.01) & (output_proposals < 0.99)
      ).sum(-1, keepdim=True) == output_proposals.shape[-1]
      # inverse_sigmoid
      output_proposals = torch.log(
          output_proposals / (1 - output_proposals)
      )
      if memory_mask is not None:
          output_proposals = output_proposals.masked_fill(
              memory_mask.unsqueeze(-1), float("inf")
          )
      output_proposals = output_proposals.masked_fill(
          ~output_proposals_valid, float("inf")
      )
  
      output_memory = memory
      if memory_mask is not None:
          output_memory = output_memory.masked_fill(
              memory_mask.unsqueeze(-1), float(0)
          )
      output_memory = output_memory.masked_fill(
          ~output_proposals_valid, float(0)
      )
      output_memory = self.memory_trans_fc(output_memory)
      output_memory = self.memory_trans_norm(output_memory)
      # [bs, sum(hw), 2]
      return output_memory, output_proposals
  
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 9 for calling the DeformableDETR obj's underlying member method code with example usage: obj.gen_encoder_output_proposals(memory, memory_mask, spatial_shapes) and returns: output_memory,  output_proposals