2016-12-05 26 views
3

我在張量流中建立了一個RNN,它採用一個可變序列並在序列的末尾進行1個預測。帶有可變長度序列的Tensorflow RNN,填充零影響學習

我零填充我的數據,以500個序列的最大長度,但在間歇許多序列將小於500

我使用dynamic_rnn並把它傳遞每個樣品的序列的長度在批處理:

# Get lstm cell output 
m.outputs, m.states = tf.nn.dynamic_rnn(
    cell=lstm_cell, 
    dtype=tf.float32, 
    sequence_length=m.X_lengths, 
    inputs=m.X) 

其中m.X_lengths是作爲佔位符變量設置的張量的序列長度。我把它傳入feed_dict

對於成本函數,它是sigmoid交叉熵(多類分類),我從m.outputs取最後一個值,並用tf.reduce_mean處理。

值得注意的是,我沒有做任何掩蔽的損失函數。我的理解是,如果我試圖使用所有輸出中所有損失的總和,則只需要掩蔽。但我只使用最後的輸出。

現在我已經在我的序列中添加了1000個填充零點,但是如果仍然只有500個序列,那麼大數列的序列長度卻是1500個序列長度。如果填充不起作用,這將學習相同,因爲沒有額外的填充。當我用這種額外的填充學習對模型進行訓練時會受到負面影響。同時將我的序列長度限制爲100可以改善結果。

問題:

  • 我可以通過在sequence_lengths一個佔位符變量?
  • 我的理解是否正確:如果我只使用dynamic_nn的最後一個輸出,我不需要掩蓋損失?
  • 有沒有在我怎麼想出來的紅旗?

回答

3

您可以傳入sequence_lengths的佔位符,並且在輸入序列中使用填充時它是必需的。一旦達到PAD符號,sequence_length參數就會通知RNN停止計算。

序列越長,需要處理的填充越多,以計算最終狀態,降低信號(如果使用的是最後一個輸出)。相反,確保你得到的'最後輸出'符合你序列的長度。例如,如果你的序列長度爲7,那麼你想要的'最後輸出'是輸出[6]。

如果確實使用dynamic_rnn()的序列長度參數,則會看到輸出[6]之後的所有輸出都只是零向量。

看到這個類似的問題:

variable-length rnn padding and mask out padding gradients

+0

如何進行模型的這種影響速度?會有更少的計算,但我想知道這是否會被一些棘手的索引和連接所抵消。 –

+0

它提高了模型的速度,因爲計算較少,但我不確定程度。如果你的模型有500次的時間步長,並且大部分時間你的序列長度爲20,這將是非常重要的。儘管如此,這是一個極端的例子。 – user2827214