class_docstr: **LSTM** 的 Decoder
  
  :param embed: ``decoder`` 输入的 embedding，支持以下几种输入类型：
  
          - ``tuple(num_embedings, embedding_dim)``，即 embedding 的大小和每个词的维度，此时将随机初始化一个 :class:`torch.nn.Embedding` 实例；
          - :class:`torch.nn.Embedding` 或 **fastNLP** 的 ``Embedding`` 对象，此时就以传入的对象作为 embedding；
          - :class:`numpy.ndarray` ，将使用传入的 ndarray 作为 Embedding 初始化；
          - :class:`torch.Tensor`，此时将使用传入的值作为 Embedding 初始化；
  :param num_layers: LSTM 的层数
  :param hidden_size: 隐藏层大小, 该值也被认为是 ``encoder`` 的输出维度大小
  :param dropout: Dropout 的大小
  :param bind_decoder_input_output_embed: ``decoder`` 的输出 embedding 是否与其输入 embedding 是一样的权重（即为同一个），若 ``embed`` 为 
      :class:`~fastNLP.embeddings.StaticEmbedding`，则 ``StaticEmbedding`` 的 ``vocab`` 不能包含 ``no_create_entry`` 的 token ，同时
      ``StaticEmbedding`` 初始化时 ``lower`` 为 ``False``，``min_freq=1``。
  :param attention: 是否使用attention
class_docstr_tok: ["*","*","LSTM","*","*","\u7684","Decoder",":","param","embed",":","``","decoder","``","\u8f93\u5165\u7684","embedding\uff0c\u652f\u6301\u4ee5\u4e0b\u51e0\u79cd\u8f93\u5165\u7c7b\u578b\uff1a","-","``","tuple","(","num_embedings",",","embedding_dim",")","``","\uff0c\u5373","embedding","\u7684\u5927\u5c0f\u548c\u6bcf\u4e2a\u8bcd\u7684\u7ef4\u5ea6\uff0c\u6b64\u65f6\u5c06\u968f\u673a\u521d\u59cb\u5316\u4e00\u4e2a",":","class",":","`","torch.nn.Embedding","`","\u5b9e\u4f8b\uff1b","-",":","class",":","`","torch.nn.Embedding","`","\u6216","*","*","fastNLP","*","*","\u7684","``","Embedding","``","\u5bf9\u8c61\uff0c\u6b64\u65f6\u5c31\u4ee5\u4f20\u5165\u7684\u5bf9\u8c61\u4f5c\u4e3a","embedding\uff1b","-",":","class",":","`","numpy.ndarray","`","\uff0c\u5c06\u4f7f\u7528\u4f20\u5165\u7684","ndarray","\u4f5c\u4e3a","Embedding","\u521d\u59cb\u5316\uff1b","-",":","class",":","`","torch.Tensor","`","\uff0c\u6b64\u65f6\u5c06\u4f7f\u7528\u4f20\u5165\u7684\u503c\u4f5c\u4e3a","Embedding","\u521d\u59cb\u5316\uff1b",":","param","num_layers",":","LSTM","\u7684\u5c42\u6570",":","param","hidden_size",":","\u9690\u85cf\u5c42\u5927\u5c0f",",","\u8be5\u503c\u4e5f\u88ab\u8ba4\u4e3a\u662f","``","encoder","``","\u7684\u8f93\u51fa\u7ef4\u5ea6\u5927\u5c0f",":","param","dropout",":","Dropout","\u7684\u5927\u5c0f",":","param","bind_decoder_input_output_embed",":","``","decoder","``","\u7684\u8f93\u51fa","embedding","\u662f\u5426\u4e0e\u5176\u8f93\u5165","embedding","\u662f\u4e00\u6837\u7684\u6743\u91cd\uff08\u5373\u4e3a\u540c\u4e00\u4e2a\uff09\uff0c\u82e5","``","embed","``","\u4e3a",":","class",":","`","~fastNLP.embeddings.StaticEmbedding","`","\uff0c\u5219","``","StaticEmbedding","``","\u7684","``","vocab","``","\u4e0d\u80fd\u5305\u542b","``","no_create_entry","``","\u7684","token","\uff0c\u540c\u65f6","``","StaticEmbedding","``","\u521d\u59cb\u5316\u65f6","``","lower","``","\u4e3a","``","False","``","\uff0c","``","min_freq=1","``","\u3002",":","param","attention",":","\u662f\u5426\u4f7f\u7528attention"]
docstr: :param tokens: ``[batch_size, max_len]``
  :param state: 保存 ``encoder`` 输出和 ``decode`` 状态的 :class:`~fastNLP.modules.torch.decoder.LSTMState` 对象
  :param return_attention: 是否返回 attention 的 score
  :return: 形状为 ``[batch_size, max_len, vocab_size]`` 的结果。如果 ``return_attention=True`` 则返回一个元组，一个元素为结果，第二个结果为
      注意力权重，形状为 ``[batch_size, max_len, encode_length]``
docstr_tok: [":","param","tokens",":","``","[","batch_size",",","max_len","]","``",":","param","state",":","\u4fdd\u5b58","``","encoder","``","\u8f93\u51fa\u548c","``","decode","``","\u72b6\u6001\u7684",":","class",":","`","~fastNLP.modules.torch.decoder.LSTMState","`","\u5bf9\u8c61",":","param","return_attention",":","\u662f\u5426\u8fd4\u56de","attention","\u7684","score",":","return",":","\u5f62\u72b6\u4e3a","``","[","batch_size",",","max_len",",","vocab_size","]","``","\u7684\u7ed3\u679c\u3002\u5982\u679c","``","return_attention=True","``","\u5219\u8fd4\u56de\u4e00\u4e2a\u5143\u7ec4\uff0c\u4e00\u4e2a\u5143\u7d20\u4e3a\u7ed3\u679c\uff0c\u7b2c\u4e8c\u4e2a\u7ed3\u679c\u4e3a","\u6ce8\u610f\u529b\u6743\u91cd\uff0c\u5f62\u72b6\u4e3a","``","[","batch_size",",","max_len",",","encode_length","]","``"]
code: def forward(
      self,
      tokens: torch.LongTensor,
      state: LSTMState,
      return_attention: bool = False,
  ):
      """
  
      :param tokens: ``[batch_size, max_len]``
      :param state: 保存 ``encoder`` 输出和 ``decode`` 状态的 :class:`~fastNLP.modules.torch.decoder.LSTMState` 对象
      :param return_attention: 是否返回 attention 的 score
      :return: 形状为 ``[batch_size, max_len, vocab_size]`` 的结果。如果 ``return_attention=True`` 则返回一个元组，一个元素为结果，第二个结果为
          注意力权重，形状为 ``[batch_size, max_len, encode_length]``
      """
      src_output = state.encoder_output
      encoder_mask = state.encoder_mask
  
      assert (
          tokens.size(1) > state.decode_length
      ), "The state does not match the tokens."
      tokens = tokens[:, state.decode_length :]
      x = self.embed(tokens)
  
      attn_weights = (
          [] if self.attention_layer is not None else None
      )  # 保存attention weight, batch,tgt_seq,src_seq
      input_feed = state.input_feed
      decoder_out = []
  
      cur_hidden = state.hidden
      cur_cell = state.cell
  
      # 开始计算
      for i in range(tokens.size(1)):
          input = torch.cat(
              (x[:, i : i + 1, :], input_feed[:, None, :]), dim=2
          )  # batch,1,2*dim
          _, (cur_hidden, cur_cell) = self.lstm(
              input, hx=(cur_hidden, cur_cell)
          )  # hidden/cell保持原来的size
          if self.attention_layer is not None:
              input_feed, attn_weight = self.attention_layer(
                  cur_hidden[-1], src_output, encoder_mask
              )
              attn_weights.append(attn_weight)
          else:
              input_feed = cur_hidden[-1]
  
          state.input_feed = input_feed  # batch, hidden
          state.hidden = cur_hidden
          state.cell = cur_cell
          state.decode_length += 1
          decoder_out.append(input_feed)
  
      decoder_out = torch.stack(
          decoder_out, dim=1
      )  # batch,seq_len,hidden
      decoder_out = self.dropout_layer(decoder_out)
      if attn_weights is not None:
          attn_weights = torch.cat(
              attn_weights, dim=1
          )  # batch, tgt_len, src_len
  
      decoder_out = self.output_proj(decoder_out)
      feats = self.output_layer(decoder_out)
  
      if return_attention:
          return feats, attn_weights
      return feats
  
imports: from typing import Union, Tuple
  import math
  import torch
  from torch import nn
  import torch.nn.functional
  from ..attention import AttentionLayer, MultiHeadAttention
  from ....embeddings.torch.utils import get_embeddings
  from ....embeddings.torch.static_embedding import StaticEmbedding
  from .seq2seq_state import State, LSTMState, TransformerState
label_desc: Use image node_id 2 for calling the LSTMSeq2SeqDecoder obj's underlying member method code with example usage: obj.forward(tokens, state, return_attention) and returns: feats, feats,  attn_weights