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 __init__(
      self,
      input_size=16,
      hidden_size=64,
      num_layers=2,
      use_attn=True,
      dropout=0.0,
      input_drop=0.0,
      noise_level=0.0,
      *args,
      **kwargs,
  ):
      super().__init__()
  
      self.input_size = input_size
      self.hidden_size = hidden_size
      self.num_layers = num_layers
      self.use_attn = use_attn
      self.noise_level = noise_level
  
      self.input_drop = nn.Dropout(input_drop)
  
      self.rnn = nn.LSTM(
          input_size=input_size,
          hidden_size=hidden_size,
          num_layers=num_layers,
          batch_first=True,
          dropout=dropout,
      )
  
      if self.use_attn:
          self.W = nn.Linear(hidden_size, hidden_size)
          self.u = nn.Linear(hidden_size, 1, bias=False)
          self.output_size = hidden_size * 2
      else:
          self.output_size = hidden_size
  
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 1 to create a new LSTM object from inherited base classes: nn with example: obj = LSTM(input_size, hidden_size, num_layers, use_attn, dropout, input_drop, noise_level)