2017-09-24 245 views
6

PyTorch的這個release似乎提供了PackedSequence用於遞歸神經網絡的可變長度輸入。但是,我發現正確使用它有點困難。如何在PyTorch中正確實現批輸入LSTM網絡?

使用pad_packed_sequence以恢復其通過pack_padded_sequence餵食RNN層的一個輸出端,我們得到了一個T x B x N張量outputs其中T是最大的時間步長,B是批量大小和N是隱藏的尺寸。我發現對於批次中的短序列,後續輸出將全部爲零。

這是我的問題。

  1. 對於單一的輸出任務,其中一個需要所有序列的最後輸出的,因爲這包含了張零分的短序列的簡單outputs[-1]會給出一個錯誤的結果。人們需要按序列長度構建索引以獲取所有序列的最後一個輸出。有更簡單的方法來做到這一點嗎?
  2. 對於多輸出任務(例如seq2seq),通常一個將增加一個線性層N x O和重塑批次輸出T x B x OTB x O並計算與真實目標TB(通常在語言模型的整數)的交叉熵損失。在這種情況下,批量輸出中的這些零是重要的嗎?

回答

3

問題1 - 最後一時間步

這是我用它來獲得最後的時間步長的輸出的代碼。我不知道是否有更簡單的解決方案。如果是這樣,我想知道它。我跟着這discussion並抓住我的last_timestep方法的相關代碼片段。這是我的前鋒。

class BaselineRNN(nn.Module): 
    def __init__(self, **kwargs): 
     ... 

    def last_timestep(self, unpacked, lengths): 
     # Index of the last output for each sequence. 
     idx = (lengths - 1).view(-1, 1).expand(unpacked.size(0), 
               unpacked.size(2)).unsqueeze(1) 
     return unpacked.gather(1, idx).squeeze() 

    def forward(self, x, lengths): 
     embs = self.embedding(x) 

     # pack the batch 
     packed = pack_padded_sequence(embs, list(lengths.data), 
             batch_first=True) 

     out_packed, (h, c) = self.rnn(packed) 

     out_unpacked, _ = pad_packed_sequence(out_packed, batch_first=True) 

     # get the outputs from the last *non-masked* timestep for each sentence 
     last_outputs = self.last_timestep(out_unpacked, lengths) 

     # project to the classes using a linear layer 
     logits = self.linear(last_outputs) 

     return logits 

問題2 - 蒙面交叉熵損失

是,默認情況下,補零個時間步長(目標)的問題。但是,掩蓋它們非常容易。你有兩個選擇,取決於你使用的PyTorch版本。

  1. PyTorch 0.2.0:現在pytorch載體直接在CrossEntropyLoss掩蔽,用ignore_index參數。例如,在語言模型或seq2seq,其中i加零填充,我屏蔽零個填充字(目標)簡單地是這樣的:

    loss_function = nn.CrossEntropyLoss(ignore_index = 0)

  2. PyTorch 0.1.12和較老:在較舊版本的PyTorch中,掩蔽不被支持,因此您必須實施自己的解決方法。我使用的解決方案是masked_cross_entropy.pyjihunchoi。您可能也對這discussion感興趣。

+0

我想你的解決方案,我得到了錯誤: 文件 「/root/PycharmProjects/skip-thoughts.torch/pytorch/tmpRNN.py」,13號線,在last_timestep 回報unpacked.gather( 1,idx).squeeze() 文件「/ usr/local/lib/python3。5/dist-packages/torch/autograd/variable.py「,第684行收集 return Gather.apply(self,dim,index) RuntimeError:save_for_backward只能保存輸入或輸出張量,但參數0不會滿足這個條件 – chenfei