class_docstr: This layer adds sinusoidal positional embeddings to a 3D input tensor. The code has been adapted from
  `Pytorch tutorial <https://pytorch.org/tutorials/beginner/transformer_tutorial.html>`_
  
  Args:
      d_model (int): dimension of the input tensor
      dropout (Optional[float]): Dropout rate. Default: 0.0
      max_len (Optional[int]): Max. number of patches (or seq. length). Default: 5000
      channels_last (Optional[bool]): Channels dimension is the last in the input tensor
  
  Shape:
      - Input: :math:`(N, C, P)` or :math:`(N, P, C)` where :math:`N` is the batch size, :math:`C` is the embedding dimension,
          :math:`P` is the number of patches
      - Output: same shape as the input
class_docstr_tok: ["This","layer","adds","sinusoidal","positional","embeddings","to","a","3D","input","tensor",".","The","code","has","been","adapted","from","`","Pytorch","tutorial","<","https",":","\/\/pytorch.org\/tutorials\/beginner\/transformer_tutorial.html",">","`","_","Args",":","d_model","(","int",")",":","dimension","of","the","input","tensor","dropout","(","Optional","[","float","]",")",":","Dropout","rate",".","Default",":","0.0","max_len","(","Optional","[","int","]",")",":","Max",".","number","of","patches","(","or","seq",".","length",")",".","Default",":","5000","channels_last","(","Optional","[","bool","]",")",":","Channels","dimension","is","the","last","in","the","input","tensor","Shape",":","-","Input",":",":","math",":","`","(","N",",","C",",","P",")","`","or",":","math",":","`","(","N",",","P",",","C",")","`","where",":","math",":","`","N","`","is","the","batch","size",",",":","math",":","`","C","`","is","the","embedding","dimension",",",":","math",":","`","P","`","is","the","number","of","patches","-","Output",":","same","shape","as","the","input"]
code: def __init__(
      self,
      d_model: int,
      dropout: Optional[float] = 0.0,
      max_len: Optional[int] = 5000,
      channels_last: Optional[bool] = True,
      *args,
      **kwargs,
  ) -> None:
      position_last = not channels_last
  
      pos_encoding = torch.zeros(max_len, d_model)
      position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(
          1
      )
      div_term = torch.exp(
          torch.arange(0, d_model, 2).float()
          * (-math.log(10000.0) / d_model)
      )
      pos_encoding[:, 0::2] = torch.sin(position * div_term)
      pos_encoding[:, 1::2] = torch.cos(position * div_term)
      # add dummy batch dimension
      pos_encoding = pos_encoding.unsqueeze(0)  # [1 x C x P_max)
  
      patch_dim = -2  # patch dimension is second last (N, P, C)
      if position_last:
          pos_encoding = pos_encoding.transpose(
              1, 2
          )  # patch dimension is last (N, C, P)
          patch_dim = -1  # patch dimension is last (N, C, P)
  
      super().__init__()
  
      self.dropout = Dropout(p=dropout)
      self.patch_dim = patch_dim
      self.register_buffer("pe", pos_encoding)
  
file_path: ml-cvnets/cvnets/layers/positional_encoding.py
imports: import math
  from typing import Optional
  import torch
  from torch import Tensor, nn
  from cvnets.layers.base_layer import BaseLayer
  from cvnets.layers.dropout import Dropout
label_desc: Use image node_id 1 to create a new SinusoidalPositionalEncoding object from inherited base classes: BaseLayer with example: obj = SinusoidalPositionalEncoding(d_model, dropout, max_len, channels_last)