从PyTorch中的BiLSTM(BiGRU)获取最后一个状态

Sma*_*y77 1 python lstm pytorch

阅读了几篇文章后,我仍然对从BiLSTM获取最后的隐藏状态的实现的正确性感到困惑。

  1. 了解PyTorch中的双向RNN(TowardsDataScience)
  2. seq2seq模型的PackedSequence(PyTorch论坛)
  3. PyTorch LSTM中的“隐藏”和“输出”之间有什么区别?(堆栈溢出)
  4. 在一批序列中选择张量(Pytorch形式)

最后一个来源(4)的方法对我来说似乎是最干净的方法,但是我仍然不确定我是否正确理解了线程。我是否在使用LSTM和反向LSTM中正确的最终隐藏状态?这是我的实现

# pos contains indices of words in embedding matrix
# seqlengths contains info about sequence lengths
# so for instance, if batch_size is 2 and pos=[4,6,9,3,1] and 
# seqlengths contains [3,2], we have batch with samples
# of variable length [4,6,9] and [3,1]

all_in_embs = self.in_embeddings(pos)
in_emb_seqs = pack_sequence(torch.split(all_in_embs, seqlengths, dim=0))
output,lasthidden = self.rnn(in_emb_seqs)
if not self.data_processor.use_gru:
    lasthidden = lasthidden[0]
# u_emb_batch has shape batch_size x embedding_dimension
# sum last state from forward and backward  direction
u_emb_batch = lasthidden[-1,:,:] + lasthidden[-2,:,:]
Run Code Online (Sandbox Code Playgroud)

这是对的吗?

igr*_*nis 5

通常,如果您要创建自己的BiLSTM网络,则需要创建两个常规LSTM,并用常规输入序列馈送一个LSTM,而用反向输入序列馈送另一个。完成两个序列的输入后,您只需从两个网络中获取最后的状态,然后以某种方式将它们捆绑在一起(求和或并置)。

据我了解,您将在此示例中使用内置BiLSTM (bidirectional=Truenn.LSTM构造函数中设置)。然后,在喂完批次后,您将获得并置输出,因为PyTorch会为您处理所有麻烦。

如果是这种情况,并且您想对隐藏状态求和,那么您必须

u_emb_batch = (lasthidden[0, :, :] + lasthidden[1, :, :])
Run Code Online (Sandbox Code Playgroud)

假设您只有一层。如果您有更多的图层,您的变体似乎会更好。

这是因为结果是结构化的(请参阅文档):

h_n的形状(num_layers * num_directions,batch,hidden_​​size):张量包含t = seq_len的隐藏状态

顺便说说,

u_emb_batch_2 = output[-1, :, :HIDDEN_DIM] + output[-1, :, HIDDEN_DIM:]
Run Code Online (Sandbox Code Playgroud)

应该提供相同的结果。

  • 1.很好,但令我惊讶的是看到不寻常的数字2.对于所有层,首先(索引0)为正常RNN,然后反转。请参阅nn.RNNBase的来源 (2认同)