中法翻譯模型
教程: https://www.tensorflow.org/versions/r0.12/tutorials/seq2seq/
目標(biāo): 訓(xùn)練一個(gè)端到端的英語(yǔ)到法語(yǔ)的翻譯模型
下面分如下幾個(gè)部分講述:
- 準(zhǔn)備代碼
- 準(zhǔn)備數(shù)據(jù)
- 運(yùn)行
- 代碼分析
準(zhǔn)備代碼
代碼地址: https://github.com/tensorflow/models/tree/master/tutorials/rnn/translate
有3個(gè)文件:
data_utils.py
seq2seq_model.py
translate.py
其中,translate.py是主腳本铐料,運(yùn)行python translate.py -h 可查看參數(shù)渐裂。seq2seq_model.py是seq2seq+attention的翻譯模型實(shí)現(xiàn),data_utils.py是處理數(shù)據(jù)的腳本钠惩,包括下載柒凉、解壓、分詞篓跛、構(gòu)建詞表膝捞、文檔id化等預(yù)處理流程。
運(yùn)行python translate.py --self_test可以測(cè)試代碼是否可以正常運(yùn)行愧沟。如果不報(bào)錯(cuò)就是ok的蔬咬。
但是由于TensorFlow框架目前更新很快,代碼很有可能不能運(yùn)行沐寺。我的機(jī)器安裝的是tensorflow-1.1.0林艘,測(cè)試上面的代碼會(huì)報(bào)錯(cuò)。查看github issue區(qū)的一些討論混坞,定位到是cell的定義有問題狐援,解決方法時(shí)修改seq2seq_model.py中的關(guān)于cell的定義:
def single_cell():
return tf.contrib.rnn.GRUCell(size, reuse=tf.get_variable_scope().reuse)
if use_lstm:
def single_cell():
return tf.contrib.rnn.BasicLSTMCell(size, reuse=tf.get_variable_scope().reuse)
def mycell():
return single_cell();
if num_layers > 1:
def mycell():
return tf.contrib.rnn.MultiRNNCell([single_cell() for _ in range(num_layers)])
# The seq2seq function: we use embedding for the input and attention.
def seq2seq_f(encoder_inputs, decoder_inputs, do_decode):
return tf.contrib.legacy_seq2seq.embedding_attention_seq2seq(
encoder_inputs,
decoder_inputs,
mycell(),
num_encoder_symbols=source_vocab_size,
num_decoder_symbols=target_vocab_size,
embedding_size=size,
output_projection=output_projection,
feed_previous=do_decode,
dtype=dtype)
修改后钢坦,再測(cè)試就是ok的了。
準(zhǔn)備數(shù)據(jù)
數(shù)據(jù)有兩份啥酱,一份是訓(xùn)練數(shù)據(jù)爹凹,一份是驗(yàn)證數(shù)據(jù)。數(shù)據(jù)都是平行語(yǔ)料镶殷,即英語(yǔ)到法語(yǔ)的句子對(duì)禾酱。
訓(xùn)練數(shù)據(jù): training-giga-fren.tar 下載地址
驗(yàn)證數(shù)據(jù): dev-v2.tgz 下載地址
在腳本data_utils.py中調(diào)用相關(guān)函數(shù)會(huì)自動(dòng)下載上述數(shù)據(jù),但是如果訓(xùn)練的機(jī)器沒有網(wǎng)絡(luò)或者下載很慢批钠,可以單獨(dú)下載之后再訓(xùn)練宇植。下載后解壓的數(shù)據(jù)情況如下:
60M dev-v2.tar
3.6G giga-fren.release2.fixed.en
4.3G giga-fren.release2.fixed.fr
2.5G training-giga-fren.tar
文件行數(shù)為2千萬行,每個(gè)文件都是一行一個(gè)句子:
22520376 giga-fren.release2.fixed.en
22520376 giga-fren.release2.fixed.fr
dev-v2.tar解壓后有許多文件埋心,只需要其中的兩個(gè)文件指郁,每個(gè)3000行:
newstest2013.en
newstest2013.fr
運(yùn)行
代碼和數(shù)據(jù)準(zhǔn)備好之后,接下來就是運(yùn)行了拷呆。
按照官網(wǎng)教程闲坎,第一步是預(yù)處理加訓(xùn)練:
python translate.py --data_dir ./data --train_dir ./train_data --en_vocab_size=40000 --fr_vocab_size=40000
其中, ./data目錄存放的是下載的訓(xùn)練語(yǔ)料和驗(yàn)證語(yǔ)料,./train_data存在訓(xùn)練的模型茬斧,英文和法文詞表大小都設(shè)置為40000腰懂,這樣其他的詞會(huì)用UNK代替,這樣設(shè)定也是為了節(jié)省訓(xùn)練時(shí)間项秉。
預(yù)處理較長(zhǎng)绣溜,需要慢慢等待。所有文件處理后+原文件有18G娄蔼,如下:
21M dev-v2.tgz
3.6G giga-fren.release2.fixed.en
1.2G giga-fren.release2.fixed.en.gz
2.3G giga-fren.release2.fixed.en.ids40000
4.3G giga-fren.release2.fixed.fr
1.3G giga-fren.release2.fixed.fr.gz
2.7G giga-fren.release2.fixed.fr.ids40000
328K newstest2013.en
228K newstest2013.en.ids40000
388K newstest2013.fr
264K newstest2013.fr.ids40000
2.5G training-giga-fren.tar
336K vocab40000.from
372K vocab40000.to
vocab40000.from 是英文詞表怖喻,vocab40000.to是法語(yǔ)詞表。
giga-fren.release2.fixed.en.ids40000 和 iga-fren.release2.fixed.fr.ids40000分別是id化的文件岁诉。
訓(xùn)練的時(shí)候讀取到2900000行進(jìn)程就被killed了锚沸,可能是占用內(nèi)存太大了。于是取部分?jǐn)?shù)據(jù)進(jìn)行訓(xùn)練,放在目錄test中:
cd test
head -n 2500000 ../data/giga-fren.release2.fixed.en > en.txt
head -n 2500000 ../data/giga-fren.release2.fixed.fr > fr.txt
cp ../data/newstest2013.en ./
cp ../data/newstest2013.fr .
cd ..
重新訓(xùn)練:
python translate.py \
--data_dir ./test \
--train_dir ./train_data \
--en_vocab_size=40000 \
--fr_vocab_size=40000 \
--from_train_data ./test/en.txt \
--to_train_data ./test/fr.txt \
--from_dev_data ./test/newstest2013.en \
--to_dev_data ./test/newstest2013.fr
如果是新的數(shù)據(jù)涕癣,則需要指定train_data和dev_data的路徑哗蜈,會(huì)調(diào)用data_utils.py中的prepare_data函數(shù)構(gòu)建詞表,然后id化坠韩。
訓(xùn)練過程中進(jìn)程還是總被killed距潘,于是降低模型參數(shù),用更少數(shù)據(jù)訓(xùn)練:
python translate.py \
--data_dir ./test \
--train_dir ./model \
--from_vocab_size=40000 \
--to_vocab_size=40000 \
--from_train_data ./test/en.txt \
--to_train_data ./test/fr.txt \
--from_dev_data ./test/newstest2013.en \
--to_dev_data ./test/newstest2013.fr \
--size=256 \
--num_layers=2 \
--max_train_data_size=1000000
翻譯case如下:
Reading model parameters from ./model/translate.ckpt-6200
> States than the number of people killed by lightning.
Les répondants ont été de plus de plus de plus de plus de plus de
> One thing is certain: these new provisions will have a negative impact on voter turn-out.
Il est pas de plus de renseignements sur les questions de ces pays .
> These restrictions are not without consequence.
Les répondants sont pas de plus de plus .
> Who is the president of the United States?
Le _UNK est le _UNK
代碼分析
官網(wǎng)教程中說tf有seq2seq的庫(kù)只搁,包含各種seq2seq模型绽昼。如基本模型basic_rnn_seq2seq,輸入就是詞語(yǔ)须蜗。而embedding模型,輸入變?yōu)樵~的embedding表示。而例子中用的是加入attention機(jī)制的embedding模型明肮,如下
def seq2seq_f(encoder_inputs, decoder_inputs, do_decode):
return tf.contrib.legacy_seq2seq.embedding_attention_seq2seq(
encoder_inputs,
decoder_inputs,
mycell(),
num_encoder_symbols=source_vocab_size,
num_decoder_symbols=target_vocab_size,
embedding_size=size,
output_projection=output_projection,
feed_previous=do_decode,
dtype=dtype)
encoder_inputs 對(duì)應(yīng)源句子中的詞
decoder_inputs 對(duì)應(yīng)目標(biāo)句子中的詞
cell 為RNNCell實(shí)例菱农,如GRUCell,LSTMCell
num_encoder_symbols encoder輸入詞表大小
num_decoder_symbols decoder輸入詞表大小
output_projection 不設(shè)定的話輸出維數(shù)可能很大(取決于詞表大小)柿估,設(shè)定的話投影到一個(gè)低維向量(by sampled softmax loss)
feed_previous True表示使用上一時(shí)刻decoder的輸出循未,F(xiàn)aslse表示使用輸入(僅訓(xùn)練時(shí)有效)
返回值為(outputs, states)
outputs 對(duì)應(yīng)decoder的輸出,與decoder_inputs長(zhǎng)度相同
states 對(duì)應(yīng)decoder每個(gè)輸出的狀態(tài)
需要注意的點(diǎn):
- Sampled softmax and output projection: 輸出要投影到低維秫舌,不然輸出會(huì)很大
- Bucketing and padding: 設(shè)定兩個(gè)語(yǔ)言長(zhǎng)度對(duì)齊的方法的妖,比如一種語(yǔ)言長(zhǎng)度為5的句子一般翻譯為另一種語(yǔ)言長(zhǎng)度為10的句子
翻譯模型基礎(chǔ)
補(bǔ)充一些基礎(chǔ)知識(shí)材料,有時(shí)間再深入看看
- 基礎(chǔ)的seq2seq模型
Learning Phrase Representations using RNN Encoder-Decoder for Statistical Machine Translation (EMNLP 2014)
有兩個(gè)RNN結(jié)構(gòu)足陨,一個(gè)編碼器嫂粟,一個(gè)解碼器,編碼器輸入為源語(yǔ)言墨缘,解碼器輸入為目標(biāo)語(yǔ)言和編碼器的輸出星虹,并且解碼器輸出翻譯結(jié)果。
在基本模型中镊讼,所有輸入都編碼為一個(gè)固定長(zhǎng)度的狀態(tài)向量宽涌,傳遞給解碼器。
- 注意力模型
Neural Machine Translation by Jointly Learning to Align and Translate
引入注意力機(jī)制后蝶棋,解碼器每一步解碼的時(shí)候都會(huì)瞥一眼輸入(peek into the input)
中英翻譯模型
找到一份聯(lián)合國(guó)的中英平行語(yǔ)料卸亮,正好跑跑中英翻譯的模型,畢竟法語(yǔ)看不懂玩裙,也不知道翻譯的如何兼贸。
語(yǔ)料準(zhǔn)備
聯(lián)合國(guó)語(yǔ)料:https://conferences.unite.un.org/UNCorpus/
點(diǎn)擊Download,填下表就可以下載献酗,有兩個(gè)文件:
1.0G UNv1.0.en-zh.tar.gz.00
299M UNv1.0.en-zh.tar.gz.01
看官網(wǎng)介紹寝受,有91,028個(gè)文件,一共15886041行罕偎。兩個(gè)文件cat到一份文件很澄,然后解壓,解壓后有如下文件:
4.0K DISCLAIMER
4.0K README
2.3G UNv1.0.en-zh.en
558M UNv1.0.en-zh.ids
1.8G UNv1.0.en-zh.zh
144K UNv1.0.pdf
UNv1.0.en-zh.en和UNv1.0.en-zh.zh就是我們想要的平行語(yǔ)料了颜及。對(duì)中文分詞甩苛,然后就可以復(fù)用之前的代碼跑模型了。
模型訓(xùn)練和預(yù)測(cè)
由于數(shù)據(jù)太大俏站,選擇了100萬行訓(xùn)練數(shù)據(jù)讯蒲,3000行驗(yàn)證數(shù)據(jù),如下:
3000 dev.en
3000 dev.zh
1000000 part.en
1000000 part.zh
中文為分詞結(jié)果肄扎,詞語(yǔ)之間用空格分隔墨林。所有文件放在目錄zh_data下赁酝,詞表大小設(shè)定為50000,訓(xùn)練模型放在./model2下旭等,運(yùn)行腳本如下:
python translate.py \
--data_dir ./zh_data \
--train_dir ./model2 \
--from_vocab_size=50000 \
--to_vocab_size=50000 \
--from_train_data ./zh_data/part.zh \
--to_train_data ./zh_data/part.en \
--from_dev_data ./zh_data/dev.zh \
--to_dev_data ./zh_data/dev.en \
--size=256 \
--num_layers=2 \
--steps_per_checkpoint=100 \
--max_train_data_size=0
訓(xùn)練后數(shù)據(jù)目錄zh_data變?yōu)椋?/p>
444K dev.en
256K dev.en.ids50000
408K dev.zh
252K dev.zh.ids50000
147M part.en
88M part.en.ids50000
132M part.zh
83M part.zh.ids50000
444K vocab50000.from
460K vocab50000.to
現(xiàn)在進(jìn)行測(cè)試酌呆,測(cè)試一定要將參數(shù)設(shè)置為和訓(xùn)練的一樣,不然加載會(huì)報(bào)錯(cuò)搔耕,測(cè)試命令:
python translate.py --decode \
--data_dir ./zh_data \
--train_dir ./model2 \
--from_vocab_size=50000 \
--to_vocab_size=50000 \
--size=256 \
--num_layers=2
迭代3400次終止:
global step 3400 learning rate 0.4950 step-time 0.18 perplexity 36.18
eval: bucket 0 perplexity 9.97
eval: bucket 1 perplexity 24.35
eval: bucket 2 perplexity 50.14
eval: bucket 3 perplexity 74.99
翻譯的結(jié)果如下:
> 他 在 干 什么
_UNK
> 通過 2015年 第 一 屆 常會(huì) 報(bào)告
Report of the report of the Conference of the General Assembly
> 審計(jì) 咨詢 委員 會(huì) 的 報(bào)告
Report of the Committee of the Committee
> 世衛(wèi)組織 的 指導(dǎo) 面向 衛(wèi)生保健 工作者 和 設(shè)施
_UNK _UNK _UNK _UNK _UNK _UNK
> 編制 一 份 指導(dǎo) 文件 草案
A decision of the draft resolution
> 第六屆 會(huì)議 的 時(shí)間 和 形式
_UNK and the Conference of the Conference of the Conference of the Republic of the
> 我 鼓勵(lì) 諸位 在 可能 的 情況 下 參加 這些 活動(dòng)
I to be be to be to be be in the work of the Republic of the Republic of the Republic of the Republic of
> 中國(guó)
China
> 美國(guó)
United Republic of the Republic of the United Republic of
> 英國(guó)
Total
> 聯(lián)合國(guó)
United Nations
> 葡萄牙
Travel
> 意大利
Australia
> 馬來西亞
Malaysia
> 法國(guó)
Germany
> 德國(guó)
Germany
> 問題
General Assembly
> 組織
United Nations
翻譯有很多不準(zhǔn)的地方隙袁,但是還是有一些效果的,畢竟訓(xùn)練的數(shù)據(jù)不是太通用弃榨,主要是聯(lián)合國(guó)官方文件菩收,而且訓(xùn)練的詞表也設(shè)定的很小,訓(xùn)練數(shù)據(jù)也只用了很小一部分鲸睛,另外訓(xùn)練數(shù)據(jù)也是需要清洗的娜饵。