class_docstr: This layer applies a self-attention with linear complexity, as described in `https://arxiv.org/abs/2206.02680`
  This layer can be used for self- as well as cross-attention.
  Args:
      embed_dim (int): :math:`C` from an expected input of size :math:`(N, C, H, W)`
      attn_drop (float): Dropout value for context scores. Default: 0.0
      bias (bool): Use bias in learnable layers. Default: True
  Shape:
      - Input: :math:`(N, C, P, N)` where :math:`N` is the batch size, :math:`C` is the input channels,
      :math:`P` is the number of pixels in the patch, and :math:`N` is the number of patches
      - Output: same as the input
  .. note::
      For MobileViTv2, we unfold the feature map [B, C, H, W] into [B, C, P, N] where P is the number of pixels
      in a patch and N is the number of patches. Because channel is the first dimension in this unfolded tensor,
      we use point-wise convolution (instead of a linear layer). This avoids a transpose operation (which may be
      expensive on resource-constrained devices) that may be required to convert the unfolded tensor from
      channel-first to channel-last format in case of a linear layer.
class_docstr_tok: ["This","layer","applies","a","self-attention","with","linear","complexity",",","as","described","in","`","https",":","\/\/arxiv.org\/abs\/2206.02680","`","This","layer","can","be","used","for","self-","as","well","as","cross-attention",".","Args",":","embed_dim","(","int",")",":",":","math",":","`","C","`","from","an","expected","input","of","size",":","math",":","`","(","N",",","C",",","H",",","W",")","`","attn_drop","(","float",")",":","Dropout","value","for","context","scores",".","Default",":","0.0","bias","(","bool",")",":","Use","bias","in","learnable","layers",".","Default",":","True","Shape",":","-","Input",":",":","math",":","`","(","N",",","C",",","P",",","N",")","`","where",":","math",":","`","N","`","is","the","batch","size",",",":","math",":","`","C","`","is","the","input","channels",",",":","math",":","`","P","`","is","the","number","of","pixels","in","the","patch",",","and",":","math",":","`","N","`","is","the","number","of","patches","-","Output",":","same","as","the","input","..","note",":",":","For","MobileViTv2",",","we","unfold","the","feature","map","[","B",",","C",",","H",",","W","]","into","[","B",",","C",",","P",",","N","]","where","P","is","the","number","of","pixels","in","a","patch","and","N","is","the","number","of","patches",".","Because","channel","is","the","first","dimension","in","this","unfolded","tensor",",","we","use","point-wise","convolution","(","instead","of","a","linear","layer",")",".","This","avoids","a","transpose","operation","(","which","may","be","expensive","on","resource-constrained","devices",")","that","may","be","required","to","convert","the","unfolded","tensor","from","channel-first","to","channel-last","format","in","case","of","a","linear","layer","."]
code: def _forward_self_attn(self, x: torch.Tensor) -> torch.Tensor:
      # [B, C, P, N] --> [B, h + 2d, P, N]
      qkv = self.qkv_proj(x)
  
      # Project x into query, key and value
      # Query --> [B, 1, P, N]
      # value, key --> [B, d, P, N]
      query, key, value = qkv.split(
          [1, self.embed_dim, self.embed_dim], dim=1
      )
  
      # apply softmax along N dimension
      context_scores = F.softmax(query, dim=-1)
      context_scores = self.attn_drop(context_scores)
  
      # Compute context vector
      # [B, d, P, N] x [B, 1, P, N] -> [B, d, P, N] --> [B, d, P, 1]
      context_vector = (key * context_scores).sum(dim=-1, keepdim=True)
  
      # combine context vector with values
      # [B, d, P, N] * [B, d, P, 1] --> [B, d, P, N]
      out = F.relu(value) * context_vector.expand_as(value)
      out = self.out_proj(out)
      out = self.out_drop(out)
      return out
  
imports: import math
  from typing import Callable, Tuple, Optional
  import torch
  import torch.nn.functional
  from torch import nn
  from timm.layers import to_2tuple, make_divisible, GroupNorm1, ConvMlp, DropPath, is_exportable
  from ._builder import build_model_with_cfg
  from ._features_fx import register_notrace_module
  from ._registry import register_model, generate_default_cfgs, register_model_deprecations
  from .byobnet import register_block, ByoBlockCfg, ByoModelCfg, ByobNet, LayerFn, num_groups
  from .vision_transformer import Block
label_desc: Use image node_id 2 for calling the LinearSelfAttention obj's underlying member method code with example usage: obj._forward_self_attn(x) and returns: out