Chainerでサクッとニューラル英日翻訳を試してみた

これはChainer Advent Calendar 2016の6日目です。

qiita.com

Chainerによる実践深層学習がとても読みやすくて面白かったので8章の翻訳モデルを参考に英日翻訳するプログラムを組んで遊んでみました。

今回の環境

今回は下記のMacBook Airで実施しました。

  • OS: macOS Sierra バージョン 10.12.1
  • プロセッサ: 1.7GHz Intel Core i7*
  • メモリ: 8GB

使ったライブラリなどのバージョンは下記の通りです。

  • Python: 3.5.1
  • Chainer: 1.18.0
  • Numpy: 1.10.4

あとはMacに形態素解析エンジンMeCabをインストール - Qiitaを参考にmecab(0.996)とIPA辞書(2.7.0-20070801)をインストールしました。

そしてPython3で形態素解析エンジンMeCabを使えるようにする(2016年3月版) - Qiitaを参考にmecab-python3もインストールしました。

訓練データ

英日翻訳を訓練するための英文と和文の対訳データはTatoeba例文と日本語索引を加工して作りました。

具体的には、まず最初に例文と日本語索引をダウンロードしました。

$ sh en2ja_data_download.sh

sentences.csvjpn_indices.csvが取得できます。

en2ja_data_download.shの中身は下記です。

そして、ダウンロードしたデータを加工して英文と和文の対訳データを作成しました。

$ python en2ja_setup.py

実行すると対訳の対応する英文と和文が同じ行になるようにそれぞれ英文ファイルen.txt、和文ファイルja.txtが作られます。 英文は全て小文字に変換、和文はmecab分かち書きに変換しています。 なお、今回は諸事情*1により訓練に使用した対訳データはランダムにサンプリングした2500対のみになります。

en2ja_setup.pyの中身は下記です。

翻訳モデル

Encoder-Decoder翻訳モデルにAttentionを導入したモデルを使ってみました。

f:id:nihma:20161206001154p:plain

モデルの説明はChainerによる実践深層学習以外では下記あたりが参考になると思います。

モデルを実装したTranslator.pyは下記です。

訓練の実施

今回は対訳データの学習を100回実施しました。 1回の学習ごとにTranslatorモデルのシリアライズデータをen2ja-[学習回数].modeというファイルに吐き出します。

$ python en2ja_learn.py
model new start.
embed_size: 100, source_size: 4503, target_size: 4350
model new finished. elapsed_time: 0.1[sec]
1 / 100 epoch start.
1 / 2500 line finished.
   ...
2500 / 2500 line finished.
1 / 100 epoch finished. elapsed_time: 329.8[sec] remaining_time: 32648.4[sec]
2 / 100 epoch start.
1 / 2500 line finished.
   ...
2500 / 2500 line finished.
100 / 100 epoch finished. elapsed_time: 303.1[sec] remaining_time: 0.0[sec]

この学習には8.5時間かかりました。 ちなみに今回の訓練では英語の語彙数は4503語、日本語の語彙数は4350語だったようです。*2

en2ja_learn.pyの中身は下記です。

翻訳のテスト

訓練の際に吐き出した各学習回数ごとのモデルを使って翻訳結果を出してみました。 en2ja_test.pyen-test.txtというファイルに書かれている英文を和文に翻訳します。

下記ではたまたま今回の訓練データに入っていたit's one thing to make plans, but quite another to carry them out.を試しに翻訳してみた結果です。訓練データの対応する和文は計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。です。

$ echo "it's one thing to make plans, but quite another to carry them out." > en-test.txt 
$ cat en-test.txt
it's one thing to make plans, but quite another to carry them out.
$ python en2ja_test.py
0: 私 は その 仕事 に は 、 私 の 人 に は 、 私 は 、 私 の 人 に は 、 私 は 、 私 の 人 に は 、 私
1: 私 は 彼 の 髪 が 好き です 。 <eos>
2: 私 達 は 、 その 仕事 に は ない 。 <eos>
3: 私 達 は 、 その 仕事 に 向い て いる 。 <eos>
4: 私 達 は 学校 で い つ そう し ない の は 、 私 達 の 言う こと が できる ん が あり ます 。 <eos>
5: テレビ は 、 乳製品 を 学ぶ ため に は 1 0 冊 の が ある 。 <eos>
6: 私 達 は 学校 を し て いる 。 <eos>
7: はい 、 眠く あり ませ ん が 、 実際 は 誰 に なっ た 。 <eos>
8: 計画 を 立てる 事 と し て いる の です が 。 <eos>
9: 計画 を 立てる 事 と 、 すぐ に は 正確 な 白鳥 を する こと が 好き だ 。 <eos>
10: 計画 を 立てる 事 と 、 すぐ に 平静 を 取り戻し た 。 <eos>
11: 計画 は 、 前例 の だ 。 <eos>
12: 計画 を 立てる 事 と し て い た 。 <eos>
13: 計画 を 立てる 事 と 、 それ は あり ます 。 <eos>
14: 計画 を 立てる 事 と 、 それ を する こと が 理解 でき ない 。 <eos>
15: 計画 を 立てる 事 と 、 すぐ に 腹 が 何 も 言わ なかっ た 。 <eos>
16: 計画 を 立てる 事 と し て も いい です 。 <eos>
17: 計画 を 立てる 事 と 、 私 は どこ で 聞け たい 。 <eos>
18: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
19: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は すぐ 帰っ て い たら 、 それ は 全く あり ませ ん 。 <eos>
20: 計画 を 立てる 事 と 、 それ は ない と 思っ て い た 。 <eos>
21: 計画 を 立てる 事 と し て も いい よ 。 <eos>
22: 計画 を 立てる 事 に は いつも 不平 たらたら だ 。 <eos>
23: 計画 を 立てる 事 と 、 それ を 実行 する こと が できる 。 <eos>
24: 計画 に は もう を し て いる 。 <eos>
25: 計画 を 立てる 事 と 、 それ は ない ため に なっ た 。 <eos>
26: 計画 を 立てる 事 と の ところ 上手く 行っ た 。 <eos>
27: 私 に は もう 車 に 忠実 で い た 。 <eos>
28: 計画 を 立てる 事 と 、 それ は 全く あり に 行き まし た 。 <eos>
29: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 の ある ラジオ だ よ 。 <eos>
30: 計画 を 立てる 事 と 、 それ を 実行 余裕 が ない 。 <eos>
31: 計画 を 立てる 事 と 、 それ は 全く 別 だ から 。 <eos>
32: 計画 を 立てる 事 と 、 今 は もう 勉強 し て いる ところ です 。 <eos>
33: 今 によって なく も びっくり し た ので 、 彼ら の 自由 に は 体 を 動かす こと が ない 。 <eos>
34: 計画 を 立てる 事 まで の ところ 上手く 行っ た 。 <eos>
35: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
36: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
37: 私 に たち の 部屋 を 先週 何 でも いっ て いる 人 が い ます 。 <eos>
38: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
39: 計画 を 立てる 事 と 、 それ は 収入 に どこ に も かしこ に も あり ませ ん 。 <eos>
40: 計画 を 立てる 事 と 、 彼 の 勇気 が 悪い 。 <eos>
41: 計画 を 立てる 事 に 会っ た 。 <eos>
42: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
43: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
44: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
45: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
46: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
47: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
48: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
49: 計画 を 立てる 事 と 、 それ が とりわけ 年少 の 者 たち に 影響 を つい た もの だ 。 <eos>
50: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
51: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
52: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
53: 計画 を 立てる 事 と 、 それ を 実行 する 事 と 関係 に なる 。 <eos>
54: 君 に は もう 宿題 を し て いる 。 <eos>
55: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
56: 計画 を 立てる 事 と 、 彼 の もの は 計画 に 不可能 と 失敗 し た 。 <eos>
57: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
58: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
59: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
60: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
61: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 の ある 経済 いくら て ない ? <eos>
62: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
63: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
64: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
65: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
66: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
67: 計画 を 立てる 事 と 、 それ を 実行 する 事 が 好き です 。 <eos>
68: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
69: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
70: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
71: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
72: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
73: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
74: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
75: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
76: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
77: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
78: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
79: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
80: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
81: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は すぐ 慣れる だろ う 。 <eos>
82: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
83: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
84: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
85: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
86: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
87: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
88: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
89: 計画 を 立てる 事 と 、 それ を 実行 する 事 と 子供 事 が わたし です 。 <eos>
90: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
91: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
92: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
93: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
94: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
95: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
96: 計画 を 立てる 事 と 、 つい 達 の 電話 す べき 事故 だ 。 <eos>
97: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
98: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>
99: 計画 を 立てる 事 と 、 それ を 実行 する 事 と は 全く 別 だ 。 <eos>

19回目の学習データで初めて正解になるもすぐに不正解になり36回目くらいから徐々に正解が出るようになってくるっぽい動きが見えて面白いです。

en2ja_test.pyの中身は下記です。

さいごに

今後は今回あまり時間がなくできなかった下記のようなことをしてみたいです。

  • 理論的な理解を深める
  • 今回できなかった大きめのデータでの訓練を実施してみる
  • パラメータを調整し精度の比較を行ってみる

*1:対訳データすべて(149704対)を使って訓練を実施しようとしたところ丸100日間ほどかかりそうだったので今回は対象を絞りました。

*2:今回しませんでしたが対訳データすべて(149704対)の場合の語彙数は40341語、日本語の語彙数は31789語だったようです。