text: from typing import Tuple
  
  import torch
  import torch.nn as nn
  from torch.autograd import Variable
  
  from auxiliary.settings import DEVICE
  
  
  class ConvLSTMCell(nn.Module):
  
      def __init__(self, input_channels, hidden_channels, kernel_size):
          super().__init__()
  
          self.device = DEVICE
  
          self.input_channels = input_channels
          self.hidden_channels = hidden_channels
          self._kernel_size = kernel_size
          self.num_features = 4
  
          self.padding = int((kernel_size - 1) / 2)
  
          self.Wxi = nn.Conv2d(self.input_channels, self.hidden_channels, self._kernel_size, 1, self.padding, bias=True)
          self.Whi = nn.Conv2d(self.hidden_channels, self.hidden_channels, self._kernel_size, 1, self.padding, bias=False)
          self.Wxf = nn.Conv2d(self.input_channels, self.hidden_channels, self._kernel_size, 1, self.padding, bias=True)
          self.Whf = nn.Conv2d(self.hidden_channels, self.hidden_channels, self._kernel_size, 1, self.padding, bias=False)
          self.Wxc = nn.Conv2d(self.input_channels, self.hidden_channels, self._kernel_size, 1, self.padding, bias=True)
          self.Whc = nn.Conv2d(self.hidden_channels, self.hidden_channels, self._kernel_size, 1, self.padding, bias=False)
          self.Wxo = nn.Conv2d(self.input_channels, self.hidden_channels, self._kernel_size, 1, self.padding, bias=True)
          self.Who = nn.Conv2d(self.hidden_channels, self.hidden_channels, self._kernel_size, 1, self.padding, bias=False)
  
          self.Wci = None
          self.Wcf = None
          self.Wco = None
  
      def forward(self, x: torch.Tensor, h: torch.Tensor, c: torch.Tensor) -> Tuple:
          ci = torch.sigmoid(self.Wxi(x) + self.Whi(h) + c * self.Wci)
          cf = torch.sigmoid(self.Wxf(x) + self.Whf(h) + c * self.Wcf)
          cc = cf * c + ci * torch.tanh(self.Wxc(x) + self.Whc(h))
          co = torch.sigmoid(self.Wxo(x) + self.Who(h) + cc * self.Wco)
          ch = co * torch.tanh(cc)
          return ch, cc
  
      def init_hidden(self, hidden: int, shape: Tuple):
          if self.Wci is None:
              self.Wci = Variable(torch.zeros(1, hidden, shape[0], shape[1])).to(self.device)
              self.Wcf = Variable(torch.zeros(1, hidden, shape[0], shape[1])).to(self.device)
              self.Wco = Variable(torch.zeros(1, hidden, shape[0], shape[1])).to(self.device)
          else:
              assert shape[0] == self.Wci.size()[2], 'Input Height Mismatched!'
              assert shape[1] == self.Wci.size()[3], 'Input Width Mismatched!'
  