code: def __init__(
      self,
      dim: int,
      key_dim: int,
      num_heads: int = 8,
      attn_ratio: float = 4.0,
      resolution: tuple[int, int] = (14, 14),
  ) -> None:
      super().__init__()
      self.num_heads = num_heads
      self.scale = key_dim**-0.5
      self.key_dim = key_dim
      self.nh_kd = key_dim * num_heads
      self.d = int(attn_ratio * key_dim)
      self.dh = int(attn_ratio * key_dim) * num_heads
      self.attn_ratio = attn_ratio
      h = self.dh + self.nh_kd * 2
  
      self.norm = nn.LayerNorm(dim)
      self.qkv = nn.Linear(dim, h)
      self.proj = nn.Linear(self.dh, dim)
  
      indices, attn_offset_size = self.build_attention_bias(resolution)
      self.attention_biases = nn.Parameter(
          torch.zeros(num_heads, attn_offset_size)
      )
      self.register_buffer(
          "attention_bias_idxs", indices, persistent=False
      )
      self.attention_bias_idxs: Tensor
      self.ab: Optional[Tensor] = None
  
imports: from __future__ import annotations
  import itertools
  import warnings
  from typing import Any, Optional
  import torch
  import torch.nn.functional
  from torch import nn
  from torch.utils import checkpoint
  from kornia.contrib.models.common import DropPath, LayerNorm2d, window_partition, window_unpartition
  from kornia.core import Module, Tensor
  from kornia.core.check import KORNIA_CHECK
label_desc: Use image node_id 1 to create a new Attention object from inherited base classes: Module with example: obj = Attention(dim, key_dim, num_heads, attn_ratio, resolution)