class_docstr: Twins Vision Transfomer (Revisiting Spatial Attention)
  
  Adapted from PVT (PyramidVisionTransformer) class at https://github.com/whai362/PVT.git
code: def __init__(
      self,
      img_size=224,
      patch_size=4,
      in_chans=3,
      num_classes=1000,
      global_pool="avg",
      embed_dims=(64, 128, 256, 512),
      num_heads=(1, 2, 4, 8),
      mlp_ratios=(4, 4, 4, 4),
      depths=(3, 4, 6, 3),
      sr_ratios=(8, 4, 2, 1),
      wss=None,
      drop_rate=0.0,
      pos_drop_rate=0.0,
      proj_drop_rate=0.0,
      attn_drop_rate=0.0,
      drop_path_rate=0.0,
      norm_layer=partial(nn.LayerNorm, eps=1e-6),
      block_cls=Block,
  ):
      super().__init__()
      self.num_classes = num_classes
      self.global_pool = global_pool
      self.depths = depths
      self.embed_dims = embed_dims
      self.num_features = embed_dims[-1]
      self.grad_checkpointing = False
  
      img_size = to_2tuple(img_size)
      prev_chs = in_chans
      self.patch_embeds = nn.ModuleList()
      self.pos_drops = nn.ModuleList()
      for i in range(len(depths)):
          self.patch_embeds.append(
              PatchEmbed(img_size, patch_size, prev_chs, embed_dims[i])
          )
          self.pos_drops.append(nn.Dropout(p=pos_drop_rate))
          prev_chs = embed_dims[i]
          img_size = tuple(t // patch_size for t in img_size)
          patch_size = 2
  
      self.blocks = nn.ModuleList()
      dpr = [
          x.item()
          for x in torch.linspace(0, drop_path_rate, sum(depths))
      ]  # stochastic depth decay rule
      cur = 0
      for k in range(len(depths)):
          _block = nn.ModuleList(
              [
                  block_cls(
                      dim=embed_dims[k],
                      num_heads=num_heads[k],
                      mlp_ratio=mlp_ratios[k],
                      proj_drop=proj_drop_rate,
                      attn_drop=attn_drop_rate,
                      drop_path=dpr[cur + i],
                      norm_layer=norm_layer,
                      sr_ratio=sr_ratios[k],
                      ws=1 if wss is None or i % 2 == 1 else wss[k],
                  )
                  for i in range(depths[k])
              ],
          )
          self.blocks.append(_block)
          cur += depths[k]
  
      self.pos_block = nn.ModuleList(
          [PosConv(embed_dim, embed_dim) for embed_dim in embed_dims]
      )
  
      self.norm = norm_layer(self.num_features)
  
      # classification head
      self.head_drop = nn.Dropout(drop_rate)
      self.head = (
          nn.Linear(self.num_features, num_classes)
          if num_classes > 0
          else nn.Identity()
      )
  
      # init weights
      self.apply(self._init_weights)
  
imports: import math
  from functools import partial
  from typing import Tuple
  import torch
  import torch.nn
  import torch.nn.functional
  from timm.data import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD
  from timm.layers import Mlp, DropPath, to_2tuple, trunc_normal_, use_fused_attn
  from ._builder import build_model_with_cfg
  from ._features_fx import register_notrace_module
  from ._registry import register_model, generate_default_cfgs
  from .vision_transformer import Attention
label_desc: Use image node_id 1 to create a new Twins object from inherited base classes: nn with example: obj = Twins(img_size, patch_size, in_chans, num_classes, global_pool, embed_dims, num_heads, mlp_ratios, depths, sr_ratios, wss, drop_rate, pos_drop_rate, proj_drop_rate, attn_drop_rate, drop_path_rate, norm_layer, block_cls)