github鏈接
注:1.2最新版本不兼容,用命令pip3 install tensorflow==1.0.0
在translate.py文件里,是調用各種函數;在seq2seq_model.py文件里,是定義了這個model的具體輸入、輸出、中間參數是怎樣的init
,以及獲取每個epoch訓練數據get_batch
和訓練方法step
。
確定這些之后再考慮各種變量的shape等問題。
代碼結構
seq2seq_model.py中定義了seq2seqModel
class結構
__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
成功進入讀取輸入的翻譯階段~由於訓練參數太小效果不理想,如下圖: