TensorFlow seq2seq模型實(shí)戰(zhàn)

中法翻譯模型

教程: https://www.tensorflow.org/versions/r0.12/tutorials/seq2seq/

目標(biāo): 訓(xùn)練一個(gè)端到端的英語(yǔ)到法語(yǔ)的翻譯模型

下面分如下幾個(gè)部分講述:

  1. 準(zhǔn)備代碼
  2. 準(zhǔn)備數(shù)據(jù)
  3. 運(yùn)行
  4. 代碼分析

準(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í)間再深入看看

  1. 基礎(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)向量宽涌,傳遞給解碼器。

  1. 注意力模型

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ù)也是需要清洗的娜饵。

其他參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市腊凶,隨后出現(xiàn)的幾起案子划咐,更是在濱河造成了極大的恐慌,老刑警劉巖钧萍,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件褐缠,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡风瘦,警方通過查閱死者的電腦和手機(jī)队魏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來万搔,“玉大人胡桨,你說我怎么就攤上這事∷脖ⅲ” “怎么了昧谊?”我有些...
    開封第一講書人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)酗捌。 經(jīng)常有香客問我呢诬,道長(zhǎng),這世上最難降的妖魔是什么胖缤? 我笑而不...
    開封第一講書人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任尚镰,我火速辦了婚禮,結(jié)果婚禮上哪廓,老公的妹妹穿的比我還像新娘狗唉。我一直安慰自己,他們只是感情好涡真,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開白布分俯。 她就那樣靜靜地躺著肾筐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪澳迫。 梳的紋絲不亂的頭發(fā)上局齿,一...
    開封第一講書人閱讀 49,079評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音橄登,去河邊找鬼。 笑死讥此,一個(gè)胖子當(dāng)著我的面吹牛拢锹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播萄喳,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼卒稳,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了他巨?” 一聲冷哼從身側(cè)響起充坑,我...
    開封第一講書人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎染突,沒想到半個(gè)月后捻爷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡份企,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年也榄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片司志。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡甜紫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出骂远,到底是詐尸還是另有隱情囚霸,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布激才,位于F島的核電站拓型,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏贸营。R本人自食惡果不足惜吨述,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望钞脂。 院中可真熱鬧揣云,春花似錦、人聲如沸冰啃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至焚刚,卻和暖如春点弯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工蟀伸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留疟羹,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓捡絮,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親莲镣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子福稳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容