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.outputs和self.losses tf.clip_by_global_norm的方法來得到self.gradient_norms和updates
step函數(進行一次訓練)里:
feed:把輸入參數的encoder_inputs、decoder_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_loss、tf.contrib.legacy_seq2seq.embedding_attention_seq2seq、tf.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是完整的
decode的時候,decoder_input只有
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]。
代碼運行說明:
- 首先用迅雷下載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
成功進入讀取輸入的翻譯階段~由於訓練參數太小效果不理想,如下圖:

