class_docstr: LSTM Model
  
  Args:
      input_size (int): input size (# features)
      hidden_size (int): hidden size
      num_layers (int): number of hidden layers
      use_attn (bool): whether use attention layer.
          we use concat attention as https://github.com/fulifeng/Adv-ALSTM/
      dropout (float): dropout rate
      input_drop (float): input dropout for data augmentation
      noise_level (float): add gaussian noise to input for data augmentation
code: def forward(self, x):
      x = self.input_drop(x)
  
      if self.training and self.noise_level > 0:
          noise = torch.randn_like(x).to(x)
          x = x + noise * self.noise_level
  
      rnn_out, _ = self.rnn(x)
      last_out = rnn_out[:, -1]
  
      if self.use_attn:
          laten = self.W(rnn_out).tanh()
          scores = self.u(laten).softmax(dim=1)
          att_out = (rnn_out * scores).sum(dim=1).squeeze()
          last_out = torch.cat([last_out, att_out], dim=1)
  
      return last_out
  
imports: import os
  import copy
  import math
  import json
  import collections
  import numpy
  import pandas
  import torch
  import torch.nn
  import torch.optim
  import torch.nn.functional
  from tqdm import tqdm
  from qlib.utils import get_or_create_path
  from qlib.log import get_module_logger
  from qlib.model.base import Model
label_desc: Use image node_id 2 for calling the LSTM obj's underlying member method code with example usage: obj.forward(x) and returns: last_out