[Note] TensorFlow seq2seq tutorial
TensorFlow 官方教學的其中一部分,是對 seq2seq 雙語翻譯模型的理論基礎及操作過程,提供簡介及說明。
該模型的目標,是將「英文」翻譯為「法文」 (Source Language: English / Target Language: French);
以下為近期閱讀及操作之後的中文筆記,將會繼續不定期補充內容,若有不正確之處也將持續更正。
[資料集]
[過程]
[操作]
[資料集]
[論文]
[參考]
[程式碼]
下載並解壓縮TensorFlow官方在github上的repo。
程式碼所在的詳細路徑為:「tensorflow-master/tensorflow/models/rnn/translate/」。
會用到的程式檔有四,分別是:「translate.py」、「seg2seq_model.py」、「data_utils.py」。
另外,還有上一層資料夾(…/rnn/)內的「seq2seq.py」,但這個程式檔內只寫了:
1
|
raise
ImportError(
"This module is deprecated. Use tf.nn.seq2seq instead."
)
|
而tf.nn.seq2seq模組內的函式,其原始程式碼可參考官方在github的seq2seq.py頁面。
[過程]
1. 資料前處理 / Preprocess
- basic_tokenizer @data_utils.py
一句句子會被空格、逗號等半形標點符號(含「”」及「’」),斷成一個詞彙列表(token list),且未做stemming等處理;網頁最後建議可設計更精緻的tokenizer。
- vocab_size @seq2seq_model.py
訓練資料集中的句子經過前述的tokenize之後,詞彙會被蒐集以建立辭典(vocabulary),並用該辭典對原始文本編碼;而文本檔經過編碼後,會在資料夾內寫出一份新檔案,例如:「newstest2013.en」 -> 「newstest2013.ids40000.en」。本模型預設的英文及法文辭典大小,皆為40,000字,若有詞彙超出辭典範圍(OOV),則會以<UNK>取代。
- Bucketing and padding @translate.py
雖然理論上RNN可以處理任意長度的句子,但實際上卻會產出相當多個graph,以配合各種英文句子長度vs.法文句子長度的組合。因此,本模型預先設定數個句長組合的bucket:
1
|
_buckets
=
[(
5
,
10
), (
10
,
15
), (
20
,
25
), (
40
,
50
)]
|
使模型僅需產出上述幾個組合的graph即可,而不必產出大量且可能有不少重複的graph。
也就是說,若有一英法句子對的長度為(8, 18),就會被分到「大於該長度對」且「bucket中的長度對最小」的一組,也就是(20, 25)。而句子不夠填滿的部分就用<PAD>填滿為止,例如編碼後長度為3的一句句子:[2, 17, 4],就會被 padding 到長度為5為止:[2, 17, 4, PAD, PAD]
–
2. 模型設定 / Model configuration
- Mechanism
在 [論文] 處所列的前3篇論文,Cho、 Sutskever、Bahdanau等提到的重要理論,依序分別為:seq2seq + GRU、Multi-layer、Attention。本模型所採用的架構,就是由上述這些理論所組合而成的。
- Model parameters @translate.py
網頁中介紹了2個主要的模型參數,分別為「num_layers」、「size」。「num_layers」就是多層seq2seq模型的層數,預設為3層;而「size」指的是一層當中的cell (GRU, LSTM, etc.)個數,預設為1024個。
另外還有「en_vocab_size」、「fr_vocab_size」及「steps_per_checkpoint」,因為名稱相當直觀就不再贅述。
- Output projection @seq2seq_model.py
模型中的decoder在產出詞彙的時候,由於target language的辭典大小為40,000字,模型勢必將會處理到維度高達40,000的tensor,而這並不是個太好的做法。
因此,本模型會使用 [論文] 第4篇論文所提出的方法。簡單來說,是使用「importance sampling」+「sampled softmax」,透過一個output_projection(一組W及b),將較小維度的output(預設為512維),投影成原先的40,000維的大小。。
–
3. 訓練 / Train
- Optimizer @seq2seq_model.py
本模型使用的是tf.train.GradientDescentOptimizer,預設learning rate為0.5,網頁建議也可使用其他的,如AdagradOptimizer。
- feed_previous @seq2seq_model.py
在訓練一個模型的時候,訓練資料集當中的真實結果(以本模型而言為法文句子)也會輸入以校正模型。
但由於RNN的decoder在前一個狀態(time stamp=t-1)的輸出(y_{t-1},也就是模型所預測出的前一個字),會成為當下狀態(time stamp=t)的輸入項之一;所以模型在預測當下這個字時,究竟是要輸入「真實的前一個字」,還是要輸入「模型自己預測的前一個字」呢?
本模型是使用feed_previous變數來決定。
當我們要訓練模型的時候,feed_previous=True,當下輸入decoder的是來自訓練資料集中的「真實的前一個字」;而當我們要測試模型的時候,feed_previous=False,當下輸入decoder的就是「模型自己預測的前一個字」了。實際操作的時候,不用去動到feed_previous,程式碼裡面已經寫好規則了。
- perplexity @translate.py
衡量翻譯模型準確度的常用指標,一般而言越小越好。
本模型在訓練時的輸出介面,會同時呈現模型分別在訓練資料集及評估資料集的perplexity,根據網頁中的描述,在經過30,000個step之後,評估資料集的數值可降低到個位數的程度。
–
4. 測試 / Test
- decode @translate.py
當模型訓練到可接受的程度之後,再次執行translate.py,且在指令碼的後面加上「- – decode」,便會開始讀取訓練完所儲存的模型檔案,例如「translate.ckpt-7000」。
接著就會開啟文字輸入介面,此時便可以輸入英文,並觀察模型輸出的法文句子。
[操作]
- 下載TensorFlow官方repo,然後cd到「translate.py」所在資料夾。
- 新增或設定「資料集資料夾(data dir)」及「模型檔資料夾(model dir)」的路徑,若沒有指定,那麼檔案就會出現在「/tmp/」當中。
- (訓練) 執行指令「python translate.py –data_dir [data dir的路徑] –train_dir [model dir的路徑] [–size=256] [–num_layers=2] [–steps_per_checkpoint=50]」,就會:1) 下載資料集;2) 建立辭典並tokenize文本;3) 訓練模型。
- 若是中途打斷訓練過程,下次在執行相同指令時,程式碼會:1) 檢查是否已有文本存在,若有就跳過下載步驟,直接訓練模型;2)檢查是否已有模型檔存在,若有就接下去繼續訓練。
- (測試) 執行指令「python translate.py –decode –data_dir [data dir的路徑] –train_dir [model dir的路徑] [–size=256] [–num_layers=2]」,就會打開前述的測試輸入介面。
[資料集]
1. 訓練資料集 / Train set
- 檔案名稱:training-giga-fren.tar
- 檔案大小:約2.6GB
- 解壓縮所需空間(含原本壓縮檔):約14GB
是在WMT’15網頁中,Parallel Data表格內的「10^9-French-English corpus」,根據網路上搜尋到的網頁1及網頁2所說*,資料來源非常多元。(*But I’m not sure if these pages exactly refer to the dataset.)
回到TensorFlow官網介紹,該資料集共有約2200萬對[英文-法文]平行語料句子,分別儲存在「giga-fren.release2.en」及「giga-fren.release2.fr」之中。
–
2. 評估資料集 / Development set
- 檔案名稱:dev-v2.tgz
- 檔案大小:約22MB
- 解壓縮所需空間(含原本壓縮檔):(可忽略)
同樣來自WMT’15網頁,是在Parallel Data表格後面的「Development sets – updated 2015-01-27」,內容以新聞為主。
因為在本模型中,只會使用解壓縮後的「newstest2013.en」及「newstest2013.fr」兩個檔案,程式碼(data_utils.py)會自動擷取上述兩個檔案,直接忽略其他檔案而不將他們解壓縮出來。
—
[論文]
該教學主要是依據以下的幾篇論文實作,在此未列出全部:
- Cho et al., 2014 (pdf) Learning Phrase Representations using RNN Encoder-Decoder for Statistical Machine Translation
- Sutskever et al., 2014 (pdf) Sequence to Sequence Learning with Neural Networks
- Bahdanau et al., 2014 (pdf) Neural Machine Translation by Jointly Learning to Align and Translate
- Jean et. al., 2014 (pdf) On Using Very Large Target Vocabulary for Neural Machine Translation
—
[參考]
本文主要參考自TensorFlow Tutorial, Sequence-to-Sequence Models:
https://www.tensorflow.org/versions/master/tutorials/seq2seq/index.html