TensorFlow seq2seq解讀


github鏈接

注:1.2最新版本不兼容,用命令pip3 install tensorflow==1.0.0

在translate.py文件里,是調用各種函數;在seq2seq_model.py文件里,是定義了這個model的具體輸入、輸出、中間參數是怎樣的init,以及獲取每個epoch訓練數據get_batch和訓練方法step
確定這些之后再考慮各種變量的shape等問題。

代碼結構

seq2seq_model.py中定義了seq2seqModelclass結構
__init__函數里:

主要定義了self的各種參數的取值。

  • (如果需要sampled softmax: 定義sampled_softmax_loss函數)
  • 定義RNN結構
  • 准備encoder_inputs等的placeholder
  • 調用seq2seq.model_with_buckets得到self.outputsself.losses
  • tf.clip_by_global_norm的方法來得到self.gradient_normsupdates
step函數(進行一次訓練)里:

feed:把輸入參數的encoder_inputsdecoder_inputs放入input_feed,最后session.run計算output的值。

get_batch函數里:

字面義,從輸入參數data中隨機選取符合要求bucket_id的數據PAD后返回。
返回結果——以self_test時的encoder_inputs為例,其格式為encoder_size*batch_size(6*32),decoder_inputs同理

translate.py是直接運行的文件
函數read_data

讀取source language和target language文件,返回n個data_set,每個里面是(source,target)的句子pair,長度符合bucket[n]的要求

函數create_model

利用seq2seq_model.py生成model結構,如果已經存在ckpt文件,則讀取參數,否則session.run(initializer)

函數train

with tf.session() as sess:

  • 調用create_model函數生成model
  • 調用read_data生成dev_set和train_set
  • training loop: 隨機選一個bucket_id->model.get_batch->model.step
函數decode

with tf.session() as sess:

  • create_model並load參數
  • 讀取待翻譯的句子,決定對應的bucket_id
  • model.get_batch->model.step
  • 取可能性最大的output,截斷
data_utils.py

生成了以上文件
ids代表把單詞轉化為了id,giga開頭的是訓練文件,newstest是測試文件,vocab里是一行一個單詞的單詞匯總。

具體分析:

1. model里調用的幾個自帶函數tf.nn.sampled_softmax_losstf.contrib.legacy_seq2seq.embedding_attention_seq2seqtf.contrib.legacy_seq2seq.model_with_buckets的關系。

tf.nn.sampled_softmax_loss,網絡本身通過sampled_softmax(W*x+b)把輸入的向量的維度擴展到target_vocab_size,這個函數是用來這一步的loss,會在后來被用於計算整體的loss。
tf.contrib.legacy_seq2seq.embedding_attention_seq2seq是不能計算的loss的,它只是負責返回這個網絡的最終輸出outputs [batch_size x decoder_size] 和狀態states[batch_size x cell.state_size]。主要參數有

encoder_inputs,
decoder_inputs,
cell

tf.contrib.legacy_seq2seq.model_with_buckets是用來和target作比較,能計算出整體的loss(sampled_softmax的loss是一部分)。返回outputs [batch_size x output_size]和losses for each bucket。主要參數有

self.encoder_inputs, self.decoder_inputs, targets,
self.target_weights, buckets,
lambda x, y: seq2seq_f(x, y, False),
softmax_loss_function=softmax_loss_function
2. train和decode時的RNN輸入和輸出是怎樣的?


train的時候,decoder_input是完整的 +W+X+Y+Z。不需要用sampled_softmax計算輸出word。
decode的時候,decoder_input只有 ,之后的decoder_input都是用上一個target。需要用sampled_softmax。

3. sess.run部分的訓練方法是怎樣的?

在model的初始化部分,定義了self.losses[len(bucket)]self.gradient_norms[len(bucket)]self.updates[len(bucket)]
在model.step部分,定義output_feed即為上述三個合並在一起。當然,要feed的只是某一個bucket,所以要指定[bucket_id]。

代碼運行說明:

  1. 首先用迅雷下載WMT語料庫(壓縮包),未避免每次運行都要重新解壓,在translate.py文件中的train函數中,把else條件改為
        from_train="../newstest2013.en.ids40000"
        to_train="../newstest2013.fr.ids40000"
        from_dev="../newstest2013.en.ids40000"
        to_dev="../newstest2013.fr.ids40000"

具體位置根據實際情況判斷,其作用是直接讀取train和dev的source和target的word_ids文件,而不用每次都重新生成。上圖中的.en.fr結尾的文件都可以刪除,因為它們是原始word組成的文件,不再需要。
2. 此命令需要運行很長時間,因為放到了服務器上。且如果不用tutorial中的小參數內存會不夠。
python translate.py --data_dir ~/omg --train_dir ~/omg/train --size=256 --num_layers=2 --steps_per_checkpoint=50
運行后會依次顯示:

Creating 2 layers of 256 units.
Created model with fresh parameters.
reading data lines XXX#作用是讀取train文件中的句子,根據長度分配到不同的bucket中

之后進行到translate.py中的while true循環中,不斷讀取數據再model.step進行訓練。同時會顯示不同bucket中的perplexity。
3. 經過~30K步(tutorial中的數據)0號1號bucket中的perplexity會下降到個位數,此時即可test。注意命令中的參數務必和train時的一樣,否則讀取checkpoint會報錯。
python translate.py --decode --data_dir ~/omg --train_dir ~/omg/train --size=256 --num_layers=2 --steps_per_checkpoint=50
成功進入讀取輸入的翻譯階段~由於訓練參數太小效果不理想,如下圖:
將United States翻譯成加拿大,不過China翻譯正確。

鏈接:https://github.com/yingtaomj/GNMT_test


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM