docstr: Generate anchors for RT-DETR.
  
  Args:
      spatial_shapes: shape (width, height) of the feature maps
      grid_size: size of the grid
      eps: specify the minimum and maximum size of the anchors
      device: device to place the anchors
      dtype: data type for the anchors
  
  Returns:
      logit of anchors and mask
docstr_tok: ["Generate","anchors","for","RT-DETR",".","Args",":","spatial_shapes",":","shape","(","width",",","height",")","of","the","feature","maps","grid_size",":","size","of","the","grid","eps",":","specify","the","minimum","and","maximum","size","of","the","anchors","device",":","device","to","place","the","anchors","dtype",":","data","type","for","the","anchors","Returns",":","logit","of","anchors","and","mask"]
code: def _generate_anchors(
      spatial_shapes: list[tuple[int, int]],
      grid_size: float = 0.05,
      eps: float = 0.01,
      device: Optional[torch.device] = None,
      dtype: Optional[torch.dtype] = None,
  ) -> tuple[Tensor, Tensor]:
      """Generate anchors for RT-DETR.
  
      Args:
          spatial_shapes: shape (width, height) of the feature maps
          grid_size: size of the grid
          eps: specify the minimum and maximum size of the anchors
          device: device to place the anchors
          dtype: data type for the anchors
  
      Returns:
          logit of anchors and mask
      """
      # TODO: might make this (or some parts of it) into a separate reusable function
      anchors_list: list[Tensor] = []
  
      for i, (h, w) in enumerate(spatial_shapes):
          # TODO: fix later kornia.utils.create_meshgrid()
          grid_y, grid_x = torch.meshgrid(
              torch.arange(h, device=device, dtype=dtype),
              torch.arange(w, device=device, dtype=dtype),
              indexing="ij",
          )
          grid_xy = torch.stack([grid_x, grid_y], -1)  # HxWx2
  
          # this satisfies onnx export
          wh = torch.empty(2, device=device, dtype=dtype)
          wh[0] = w
          wh[1] = h
  
          grid_xy = (grid_xy + 0.5) / wh  # normalize to [0, 1]
          grid_wh = torch.ones_like(grid_xy) * grid_size * (2.0**i)
          anchors_list.append(
              concatenate([grid_xy, grid_wh], -1).reshape(-1, h * w, 4)
          )
  
      anchors = concatenate(anchors_list, 1)
      valid_mask = ((anchors > eps) * (anchors < 1 - eps)).all(
          -1, keepdim=True
      )
      anchors = torch.log(
          anchors / (1 - anchors)
      )  # anchors.logit() fails ONNX export
  
      inf_t = torch.empty(1, device=device, dtype=dtype)
      inf_t[0] = torch.inf
  
      anchors = torch.where(valid_mask, anchors, inf_t)
  
      return anchors, valid_mask
  
imports: from __future__ import annotations
  from typing import Optional
  import torch
  from torch import nn
  from kornia.contrib.models.common import MLP, ConvNormAct
  from kornia.core import Module, Tensor, concatenate
label_desc: Use image node_id 5 for calling the RTDETRHead obj's underlying member method code with example usage: obj._generate_anchors(spatial_shapes, grid_size, eps, device, dtype) and returns: anchors,  valid_mask