class_docstr: Separable Conv2D in pytorch
  
  Args:
      in_c (`int`):
          Number of channels in the input image.
      out_c (`int`):
          Number of channels produced by the convolution.
      kernel_size (`Union[int, Tuple]`):
          Size of the convolving kernel.
      stride (`Union[int, Tuple]`):
          Stride of the convolution.
      in_f (`int`):
          Padding parameter.
      in_t (`int`):
          Padding parameter.
      fuller (`bool=False`):
          Whether to use group in conv2 layer.
      activation (`nn.Module=nn.ReLU()`):
          Activation layer.
      relu_after_bn (`bool=False`):
          Whether to add ReLU after batch norm.
code: def __init__(
      self,
      in_c: int,
      out_c: int,
      kernel_size: Union[int, Tuple],
      stride: Union[int, Tuple],
      in_f: int,
      in_t: int,
      fuller: bool = False,
      activation: nn.Module = nn.ReLU(),
      relu_after_bn: bool = False,
  ):
      super().__init__()
      # Same padding
      padding = (in_t - 1) // stride[0] * stride[0] + kernel_size - in_t
      self.pad1 = nn.ZeroPad2d(
          (padding // 2, padding - padding // 2, 0, 0)
      )
      self.conv1 = nn.Conv2d(
          in_c,
          out_c,
          kernel_size=(1, kernel_size),
          stride=(1, stride[0]),
      )
      self.ln1 = nn.LayerNorm(
          (out_c, in_f, (in_t - 1) // stride[0] + 1)
      )
      self.relu1 = activation
      # Same padding
      padding = (in_f - 1) // stride[1] * stride[1] + kernel_size - in_f
      self.pad2 = nn.ZeroPad2d(
          (0, 0, padding // 2, padding - padding // 2)
      )
      if fuller:
          self.conv2 = nn.Conv2d(
              out_c,
              out_c,
              kernel_size=(kernel_size, 1),
              stride=(stride[1], 1),
          )
      else:
          self.conv2 = nn.Conv2d(
              out_c,
              out_c,
              kernel_size=(kernel_size, 1),
              stride=(stride[1], 1),
              groups=out_c,
          )
      self.ln2 = nn.LayerNorm(
          (
              out_c,
              (in_f - 1) // stride[1] + 1,
              (in_t - 1) // stride[0] + 1,
          )
      )
      self.relu2 = activation
  
      self.relu_after_bn = relu_after_bn
      self.hacked = False
  
imports: import torch
  from torch import nn
  from typing import Union, Tuple
label_desc: Use image node_id 1 to create a new SeparableConv2d object from inherited base classes: nn with example: obj = SeparableConv2d(in_c, out_c, kernel_size, stride, in_f, in_t, fuller, activation, relu_after_bn)