class_docstr: Modified Attention.
  
  Args:
      dim (`int`): feature dimension
      num_heads (`int`): number of attention heads
      qkv_bias (`bool`): flag to use bias for qkv
      qk_scale (`int`): Number to scale qk
      attn_drop (`float`): drop rate of attention
      proj_drop (`float`): drop rate of projection
      sr_ratio (`int`): shunt rate
class_docstr_tok: ["Modified","Attention",".","Args",":","dim","(","`","int","`",")",":","feature","dimension","num_heads","(","`","int","`",")",":","number","of","attention","heads","qkv_bias","(","`","bool","`",")",":","flag","to","use","bias","for","qkv","qk_scale","(","`","int","`",")",":","Number","to","scale","qk","attn_drop","(","`","float","`",")",":","drop","rate","of","attention","proj_drop","(","`","float","`",")",":","drop","rate","of","projection","sr_ratio","(","`","int","`",")",":","shunt","rate"]
code: def __init__(
      self,
      dim,
      num_heads=8,
      qkv_bias=False,
      qk_scale=None,
      attn_drop=0.0,
      proj_drop=0.0,
      sr_ratio=1,
  ):
      super().__init__()
      assert (
          dim % num_heads == 0
      ), f"dim {dim} should be divisible by num_heads {num_heads}."
  
      self.dim = dim
      self.num_heads = num_heads
      head_dim = dim // num_heads
      self.scale = qk_scale or head_dim**-0.5
  
      self.q = nn.Linear(dim, dim, bias=qkv_bias)
  
      self.attn_drop = nn.Dropout(attn_drop)
      self.proj = nn.Linear(dim, dim)
      self.proj_drop = nn.Dropout(proj_drop)
  
      self.sr_ratio = sr_ratio
      if sr_ratio > 1:
          self.act = nn.GELU()
          if sr_ratio in [8, 4, 2]:
              self.sr1 = nn.Conv2d(
                  dim, dim, kernel_size=sr_ratio, stride=sr_ratio
              )
              self.norm1 = nn.LayerNorm(dim)
              self.sr2 = nn.Conv2d(
                  dim,
                  dim,
                  kernel_size=sr_ratio // 2,
                  stride=sr_ratio // 2,
              )
              self.norm2 = nn.LayerNorm(dim)
          self.kv1 = nn.Linear(dim, dim, bias=qkv_bias)
          self.kv2 = nn.Linear(dim, dim, bias=qkv_bias)
          self.local_conv1 = nn.Conv2d(
              dim // 2,
              dim // 2,
              kernel_size=3,
              padding=1,
              stride=1,
              groups=dim // 2,
          )
          self.local_conv2 = nn.Conv2d(
              dim // 2,
              dim // 2,
              kernel_size=3,
              padding=1,
              stride=1,
              groups=dim // 2,
          )
      else:
          self.kv = nn.Linear(dim, dim * 2, bias=qkv_bias)
          self.local_conv = nn.Conv2d(
              dim, dim, kernel_size=3, padding=1, stride=1, groups=dim
          )
      self.apply(init_vit_weights)
  
imports: import torch
  from torch import nn
  from towhee.models.layers.patch_embed2d import PatchEmbed2D
  from towhee.models.layers.mlp import Mlp
  from towhee.models.layers.droppath import DropPath
  from towhee.models.utils.init_vit_weights import init_vit_weights
label_desc: Use image node_id 1 to create a new Attention object from inherited base classes: nn with example: obj = Attention(dim, num_heads, qkv_bias, qk_scale, attn_drop, proj_drop, sr_ratio)