Pointer-network的tensorflow實現-1

pointer-network是最近seq2seq比較火的一個分支,在基於深度學習的閱讀理解,摘要系統中都被普遍應用。 python

感興趣的能夠閱讀原paper 推薦閱讀 git

https://medium.com/@devnag/pointer-networks-in-tensorflow-with-sample-code-14645063f264 github

   

這個思路也是比較簡單 就是解碼的預測限定在輸入的位置上 這在不少地方有用 小程序

好比考慮機器翻譯的大詞典問題,詞彙太多了不少詞是長尾的,詞向量訓練是不充分的,那麼seq2seq翻譯的時候很難翻譯出這些詞 另外專名什麼的 不少是能夠copy 解碼輸出的 網絡

另外考慮文本摘要,不少時候就是要copy輸入原文中的詞,特別是長尾專名 更好的方式是copy而不是generate app

   

網絡上有一些pointer-network的實現,比較推薦 ide

 https://github.com/ikostrikov/TensorFlow-Pointer-Networks 學習

這個做爲入門示例比較好,使用簡單的static rnn 實現更好理解,固然 dynamic速度更快,可是從學習角度 ui

先實現static更好一些。 this

Dynamic rnn的 pointer network實現

https://github.com/devsisters/pointer-network-tensorflow 

這裏對static rnn實現的作了一個拷貝並作了小修改,改正了其中的一些問題 參見 https://github.com/chenghuige/hasky/tree/master/applications/pointer-network/static

   

這個小程序對應的應用是輸入一個序列 好比,輸出排序結果

   

咱們的構造數據

python dataset.py

EncoderInputs: [array([[ 0.74840968]]), array([[ 0.70166106]]), array([[ 0.67414996]]), array([[ 0.9014052]]), array([[ 0.72811645]])]

DecoderInputs: [array([[ 0.]]), array([[ 0.67414996]]), array([[ 0.70166106]]), array([[ 0.72811645]]), array([[ 0.74840968]]), array([[ 0.9014052]])]

TargetLabels: [array([[ 3.]]), array([[ 2.]]), array([[ 5.]]), array([[ 1.]]), array([[ 4.]]), array([[ 0.]])]

   

訓練過程當中的eval展現:

2017-06-07 22:35:52 0:28:19 eval_step: 111300 eval_metrics:

['eval_loss:0.070', 'correct_predict_ratio:0.844']

label--: [ 2 6 1 4 9 7 10 8 5 3 0]

predict: [ 2 6 1 4 9 7 10 8 5 3 0]

label--: [ 1 6 2 5 8 3 9 4 10 7 0]

predict: [ 1 6 2 5 3 3 9 4 10 7 0]

   

大概是這樣 第一個咱們認爲是預測徹底正確了, 第二個預測不徹底正確

   

原程序最主要的問題是 Feed_prev 設置爲True的時候 原始代碼有問題的 由於inp使用的是decoder_input這是不正確的由於

預測的時候實際上是沒有decoder_input輸入的,原代碼預測的時候decoder input強制copy/feed了encoder_input

這在邏輯是是有問題的。 實驗效果也證實修改爲訓練也使用encoder_input來生成inp效果好不少。

   

那麼關於feed_prev咱們知道在預測的時候是必須設置爲True的由於,預測的時候沒有decoder_input咱們的下一個輸出依賴

上一個預測的輸出。

訓練的時候咱們是用decoder_input序列訓練(feed_prev==False)仍是也使用自身預測產生的結果進行下一步預測feed_prev==True呢

參考tensorflow官網的說明

In the above invocation, we set feed_previous to False. This means that the decoder will use decoder_inputstensors as provided. If we set feed_previous to True, the decoder would only use the first element of decoder_inputs. All other tensors from this list would be ignored, and instead the previous output of the decoder would be used. This is used for decoding translations in our translation model, but it can also be used during training, to make the model more robust to its own mistakes, similar to Bengio et al., 2015 (pdf).

   

來自 <https://www.tensorflow.org/tutorials/seq2seq>

   

這裏使用

train.sh train-no-feed-prev.sh 作了對比實驗

訓練時候使用feed_prev==True效果稍好(紅色) 特別是穩定性方差小一些

相關文章
相關標籤/搜索