docstr: Implementation of multi-head attention layer of the original transformer model.
  einsum and einops.rearrange is used whenever possible
  Args:
      dim: token's dimension, i.e. word embedding vector size
      heads: the number of distinct representations to learn
      dim_head: the dim of the head. In general dim_head<dim.
      However, it may not necessary be (dim/heads)
code: def __init__(self, dim, heads=8, dim_head=None):
      """
      Implementation of multi-head attention layer of the original transformer model.
      einsum and einops.rearrange is used whenever possible
      Args:
          dim: token's dimension, i.e. word embedding vector size
          heads: the number of distinct representations to learn
          dim_head: the dim of the head. In general dim_head<dim.
          However, it may not necessary be (dim/heads)
      """
      super().__init__()
      self.dim_head = (
          (int(dim / heads)) if dim_head is None else dim_head
      )
      _dim = self.dim_head * heads
      self.heads = heads
      self.to_qvk = nn.Linear(dim, _dim * 3, bias_attr=False)
      self.W_0 = nn.Linear(_dim, dim, bias_attr=False)
      self.scale_factor = self.dim_head**-0.5
  
imports: from typing import List, Tuple
  import numpy
  import paddle
  import paddle.nn
  from paddle import Tensor
  from medicalseg.cvlibs import manager
label_desc: Use image node_id 1 to create a new MultiHeadSelfAttention object from inherited base classes: nn with example: obj = MultiHeadSelfAttention(dim, heads, dim_head)