text: 
  import torch
  import torch.nn as nn
  class RNN(nn.Module):
      def __init__(self, vocab_size, embedding_dim, hidden_dim, output_dim, n_layers,
                   bidirectional, dropout, pad_idx, rnn_type):
  
  
          super().__init__()
          self.rnn_type = rnn_type
  
          self.embedding = nn.Embedding(vocab_size, embedding_dim, padding_idx=pad_idx)
          if rnn_type == 'lstm':
              self.rnn = nn.LSTM(embedding_dim,
                                 hidden_dim,
                                 num_layers=n_layers,
                                 bidirectional=bidirectional,
                                 dropout=dropout)
          else:
              self.rnn = nn.GRU(embedding_dim,
                                 hidden_dim,
                                 num_layers=n_layers,
                                 bidirectional=bidirectional,
                                 dropout=dropout)
  
          if bidirectional:
              self.fc = nn.Linear(hidden_dim * 2, output_dim)
          else:
              self.fc = nn.Linear(hidden_dim , output_dim)
  
          self.dropout = nn.Dropout(dropout)
  
  
      def forward(self, text, text_lengths):
          # text = [sent len, batch size]
  
          embedded = self.dropout(self.embedding(text))
  
          # embedded = [sent len, batch size, emb dim]
  
          # pack sequence
          packed_embedded = nn.utils.rnn.pack_padded_sequence(embedded, text_lengths.cpu(), enforce_sorted=False)
          if self.rnn_type == 'lstm':
              packed_output, (hidden, cell) = self.rnn(packed_embedded)
          else:
              packed_output, hidden = self.rnn(packed_embedded)
  
  
          # unpack sequence
          output, output_lengths = nn.utils.rnn.pad_packed_sequence(packed_output,batch_first=True)
  
          # output = [sent len, batch size, hid dim * num directions]
          # output over padding tokens are zero tensors
  
          # hidden = [num layers * num directions, batch size, hid dim]
          # cell = [num layers * num directions, batch size, hid dim]
  
          # concat the final forward (hidden[-2,:,:]) and backward (hidden[-1,:,:]) hidden layers
          # and apply dropout
          if hidden.shape[0]<=1:
              hidden = hidden.squeeze_(0)
              hidden = self.dropout(hidden)#torch.cat((hidden[-2, :, :], hidden[-1, :, :]), dim=1))
          else:
              hidden = self.dropout(torch.cat((hidden[-2, :, :], hidden[-1, :, :]), dim=1))
  
  
  
          return self.fc(hidden),output,output_lengths
  
  def epoch_time(start_time, end_time):
      elapsed_time = end_time - start_time
      elapsed_mins = int(elapsed_time / 60)
      elapsed_secs = int(elapsed_time - (elapsed_mins * 60))
      return elapsed_mins, elapsed_secs