class_docstr: A complete encoder-decoder model, with optional attention.
  
  A parent class which makes use of the contextual_embedding (such as a charlm)
  can make use of unsaved_modules when saving.
class_docstr_tok: ["A","complete","encoder-decoder","model",",","with","optional","attention",".","A","parent","class","which","makes","use","of","the","contextual_embedding","(","such","as","a","charlm",")","can","make","use","of","unsaved_modules","when","saving","."]
code: def __init__(self, args, emb_matrix=None, contextual_embedding=None):
      super().__init__()
  
      self.unsaved_modules = []
  
      self.vocab_size = args["vocab_size"]
      self.emb_dim = args["emb_dim"]
      self.hidden_dim = args["hidden_dim"]
      self.nlayers = args[
          "num_layers"
      ]  # encoder layers, decoder layers = 1
      self.emb_dropout = args.get("emb_dropout", 0.0)
      self.dropout = args["dropout"]
      self.pad_token = constant.PAD_ID
      self.max_dec_len = args["max_dec_len"]
      self.top = args.get("top", 1e10)
      self.args = args
      self.emb_matrix = emb_matrix
      self.add_unsaved_module(
          "contextual_embedding", contextual_embedding
      )
  
      logger.debug("Building an attentional Seq2Seq model...")
      logger.debug("Using a Bi-LSTM encoder")
      self.num_directions = 2
      self.enc_hidden_dim = self.hidden_dim // 2
      self.dec_hidden_dim = self.hidden_dim
  
      self.use_pos = args.get("pos", False)
      self.pos_dim = args.get("pos_dim", 0)
      self.pos_vocab_size = args.get("pos_vocab_size", 0)
      self.pos_dropout = args.get("pos_dropout", 0)
      self.edit = args.get("edit", False)
      self.num_edit = args.get("num_edit", 0)
      self.copy = args.get("copy", False)
  
      self.emb_drop = nn.Dropout(self.emb_dropout)
      self.drop = nn.Dropout(self.dropout)
      self.embedding = nn.Embedding(
          self.vocab_size, self.emb_dim, self.pad_token
      )
      self.input_dim = self.emb_dim
      if self.contextual_embedding is not None:
          self.input_dim += self.contextual_embedding.hidden_dim()
      self.encoder = nn.LSTM(
          self.input_dim,
          self.enc_hidden_dim,
          self.nlayers,
          bidirectional=True,
          batch_first=True,
          dropout=self.dropout if self.nlayers > 1 else 0,
      )
      self.decoder = LSTMAttention(
          self.emb_dim,
          self.dec_hidden_dim,
          batch_first=True,
          attn_type=self.args["attn_type"],
      )
      self.dec2vocab = nn.Linear(self.dec_hidden_dim, self.vocab_size)
      if self.use_pos and self.pos_dim > 0:
          logger.debug("Using POS in encoder")
          self.pos_embedding = nn.Embedding(
              self.pos_vocab_size, self.pos_dim, self.pad_token
          )
          self.pos_drop = nn.Dropout(self.pos_dropout)
      if self.edit:
          edit_hidden = self.hidden_dim // 2
          self.edit_clf = nn.Sequential(
              nn.Linear(self.hidden_dim, edit_hidden),
              nn.ReLU(),
              nn.Linear(edit_hidden, self.num_edit),
          )
  
      if self.copy:
          self.copy_gate = nn.Linear(self.dec_hidden_dim, 1)
  
      SOS_tensor = torch.LongTensor([constant.SOS_ID])
      self.register_buffer("SOS_tensor", SOS_tensor)
  
      self.init_weights()
  
imports: import logging
  import torch
  from torch import nn
  import torch.nn.functional
  import numpy
  import stanza.models.common.seq2seq_constant
  from stanza.models.common import utils
  from stanza.models.common.seq2seq_modules import LSTMAttention
  from stanza.models.common.beam import Beam
label_desc: Use image node_id 1 to create a new Seq2SeqModel object from inherited base classes: nn with example: obj = Seq2SeqModel(args, emb_matrix, contextual_embedding)