class_docstr: This is an implementation of convolution module in Conformer.
  
  Arguments
  ----------
  input_size : int
      The expected size of the input embedding dimension.
  kernel_size: int, optional
      Kernel size of non-bottleneck convolutional layer.
  bias: bool, optional
      Whether to use bias in the non-bottleneck conv layer.
  activation: torch.nn.Module
       Activation function used after non-bottleneck conv layer.
  dropout: float, optional
       Dropout rate.
  causal: bool, optional
       Whether the convolution should be causal or not.
  dilation: int, optional
       Dilation factor for the non bottleneck conv layer.
  
  Example
  -------
  >>> import torch
  >>> x = torch.rand((8, 60, 512))
  >>> net = ConvolutionModule(512, 3)
  >>> output = net(x)
  >>> output.shape
  torch.Size([8, 60, 512])
code: def __init__(
      self,
      input_size,
      kernel_size=31,
      bias=True,
      activation=Swish,
      dropout=0.0,
      causal=False,
      dilation=1,
  ):
      super().__init__()
  
      self.kernel_size = kernel_size
      self.causal = causal
      self.dilation = dilation
  
      if self.causal:
          self.padding = (kernel_size - 1) * 2 ** (dilation - 1)
      else:
          self.padding = (kernel_size - 1) * 2 ** (dilation - 1) // 2
  
      self.layer_norm = nn.LayerNorm(input_size)
      self.bottleneck = nn.Sequential(
          # pointwise
          nn.Conv1d(
              input_size,
              2 * input_size,
              kernel_size=1,
              stride=1,
              bias=bias,
          ),
          nn.GLU(dim=1),
      )
      # depthwise
      self.conv = nn.Conv1d(
          input_size,
          input_size,
          kernel_size=kernel_size,
          stride=1,
          padding=self.padding,
          dilation=dilation,
          groups=input_size,
          bias=bias,
      )
  
      # NOTE: there appears to be a mismatch compared to the Conformer paper:
      # I believe the first LayerNorm below is supposed to be a BatchNorm.
  
      self.after_conv = nn.Sequential(
          nn.LayerNorm(input_size),
          activation(),
          # pointwise
          nn.Linear(input_size, input_size, bias=bias),
          nn.Dropout(dropout),
      )
  
imports: from dataclasses import dataclass
  import torch
  import torch.nn
  import torch.nn.functional
  from typing import Optional, List
  import speechbrain
  import warnings
  from speechbrain.nnet.attention import RelPosMHAXL, MultiheadAttention, PositionalwiseFeedForward
  from speechbrain.utils.dynamic_chunk_training import DynChunkTrainConfig
  from speechbrain.lobes.models.transformer.hypermixing import HyperMixing
  from speechbrain.nnet.normalization import LayerNorm
  from speechbrain.nnet.activations import Swish
label_desc: Use image node_id 1 to create a new ConvolutionModule object from inherited base classes: nn with example: obj = ConvolutionModule(input_size, kernel_size, bias, activation, dropout, causal, dilation)