標籤:black tor 推薦閱讀 向量 sim pointer 簡單的 loss 簡單
pointer-network是最近seq2seq比較火的一個分支,在基於深度學習的閱讀理解,摘要系統中都被廣泛應用。
感興趣的可以閱讀原paper 推薦閱讀
https://medium.com/@devnag/pointer-networks-in-tensorflow-with-sample-code-14645063f264
??
這個思路也是比較簡單就是解碼的預測限定在輸入的位置上這在很多地方有用
比如考慮機器翻譯的大詞典問題,詞彙太多了很多詞是長尾的,詞向量訓練是不充分的,那麼seq2seq翻譯的時候很難翻譯出這些詞另外專名什麼的很多是可以copy到解碼輸出的
另外考慮文本摘要,很多時候就是要copy輸入原文中的詞,特別是長尾專名更好的方式是copy而不是generate
??
網路上有一些pointer-network的實現,比較推薦
?https://github.com/ikostrikov/TensorFlow-Pointer-Networks
這個作為入門樣本比較好,使用簡單的static rnn 實現更好理解,當然 dynamic速度更快,但是從學習角度
先實現static更好一些。
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效果稍好(紅色) 特別是穩定性方差小一些
??
??
Pointer-network的tensorflow實現-1