はじめに
Google Colabでも、機械学習による翻訳が動くので試してみた。OpenNMT-pyのデフォルトデータでは、英独翻訳ができる。さらに、英和翻訳のコーパス(KFTT等)を使えば、英和翻訳が出来る。
#手順(英独翻訳)
環境設定
OpenNMT-pyをダウンロードする。
!pwd
!ls
!git clone https://github.com/OpenNMT/OpenNMT-py.git
Pythonパッケージの設定を行う。
!cd OpenNMT-py;pip install -r requirements.txt
前処理
学習前の処理を行う。
!python OpenNMT-py/preprocess.py -train_src '/content/OpenNMT-py/data/'src-train.txt -train_tgt '/content/OpenNMT-py/data/'tgt-train.txt -valid_src '/content/OpenNMT-py/data/'src-val.txt -valid_tgt '/content/OpenNMT-py/data/'tgt-val.txt -save_data '/content/OpenNMT-py/data/'demo
学習
GPUを使用するため、gpu_ranksフラグを設定する。しかし、GPUを使っても、デフォルトでは、学習に10時間程度かかる。ここでは、ステップ数を一桁減らしてtrain_stepsで指定して1万で行う。なお、CPUのみで実行した場合、20倍以上余分に計算時間がかかる。また、Google Colabでは、K80からTesla T4に変わったようで、2.5倍近く処理速度が上がっている。
また、引数はいろいろあり細かく設定出来るので、helpコマンドもしくは、ソースコード(下記)を見て確認したほうが良い。
!python OpenNMT-py/train.py -gpu_ranks 0 --train_steps 10000 -save_model '/content/OpenNMT-py/data/'data-model -data '/content/OpenNMT-py/data/'demo
たとえば、以下のような出力が現れる。accは、accuracyを示す。このため100に出来るだけ近いほうが良い。pplは、perplexityを示す。このため、1に出来るだけ近いほうが良い。xentは、CrossEntropyを示す。このため、出来るだけ小さい数字が良い。
[2019-03-26 15:09:20,472 INFO] Step 10000/10000; acc: 74.59; ppl: 2.75; xent: 1.01; lr: 1.00000; 4195/4177 tok/s; 3528 sec
翻訳
英独翻訳であるが以下のようにして出来る。
!python OpenNMT-py/translate.py -model '/content/OpenNMT-py/data/'data-model_step_10000.pt -src '/content/OpenNMT-py/data/'src-test.txt -output pred.txt -replace_unk -verbose
#手順(英和翻訳)
環境設定
英独翻訳と同じである。なお、データが異なるのでその部分だけ記載する。
KFTTは、京都に関するWikipediaを人手で翻訳したコーパスである。このため、翻訳記事は京都に限られると考えられる。詳細は、コーパスの説明を参照のこと。
!wget http://www.phontron.com/kftt/download/kftt-data-1.0.tar.gz
!tar xzf kftt-data-1.0.tar.gz
!ls kftt-data-1.0/data/tok
!cp -r kftt-data-1.0/data/tok OpenNMT-py/kftt
!ls OpenNMT-py/kftt
前処理
前処理を、行う。この際、引数は以下の表の通りである。なお、ディレクトリは、dataをkfttに置き換えている。
!python OpenNMT-py/preprocess.py -train_src '/content/OpenNMT-py/kftt/'kyoto-train.en -train_tgt '/content/OpenNMT-py/kftt/'kyoto-train.ja -valid_src '/content/OpenNMT-py/kftt/'kyoto-dev.en -valid_tgt '/content/OpenNMT-py/kftt/'kyoto-dev.ja -save_data '/content/OpenNMT-py/kftt/'demo
引数 | KFTTデータ | OpenMNT-py英独データ |
---|---|---|
train_src | kyoto-train.en | src-train.txt |
train_tgt | kyoto-train.ja | tgt-train.txt |
valid_src | kyoto-dev.en | src-val.txt |
valid_tgt | kyoto-dev.ja | tgt-val.txt |
学習
基本的に行う処理は、英独翻訳と同じである。
!python OpenNMT-py/train.py -gpu_ranks 0 --train_steps 10000 -save_model '/content/OpenNMT-py/kftt/'data-model -data '/content/OpenNMT-py/kftt/'demo
以下に、英和翻訳の学習の値を比較してみる。(本来テストデータを比較すべきであるが、暫定的に学習データのまま)
明らかに、同じステップ数では精度が上がらない(難しい言語である)ことがわかる。
[2019-03-27 16:47:41,631 INFO] Step 10000/10000; acc: 45.61; ppl: 22.33; xent: 3.11; lr: 1.00000; 3301/3572 tok/s; 4007 sec
10000ステップ学習後の値は以下の通りである。英和だと更なる学習が必要であることがわかる。
パラメータ | KFTTデータ | OpenMNT-py英独データ |
---|---|---|
acc | 45.61 | 74.59 |
ppl | 22.33 | 2.75 |
xent | 3.11 | 1.01 |
翻訳
!python OpenNMT-py/translate.py -model '/content/OpenNMT-py/kftt/'data-model_step_10000.pt -src '/content/OpenNMT-py/kftt/'kyoto-test.en -output pred.txt -replace_unk -verbose
最後に
ほかにもいろいろな機能がある。たとえば、REST APIサーバ(server.py)とか、TensorBoardへの出力が出来る。さらに精度を上げる方法について。ご存知の通り、Google Colabでは12時間でインスタンスは止まるが、チェックポイント機能(5000エポックで自動的に保存される)を使いgoogle drive等に保存しながら、繰り返し実行し、精度を上げることが出来る。とはいえ、Volta等高性能GPUを使うなどを考えたほうが良いとおもう。
参考資料
- OpenNMT
- フォーラム (OpenNMTに関する質問等はここに投げる。)
- (論文)[OpenNMT: Open-Source Toolkit for Neural Machine Translation](OpenNMT: Open-Source Toolkit for Neural Machine Translation)
- OpenNMT-py
- OpenNMT-py
- Quick Start
- OpenNMT-py/onmt/opts.py 各種スクリプトの引数を記載しているコード
- preprocess.py
-
train.py
-
main()
-
onmt.single_main.main
-
build_model(モデル生成器)
-
build_base_model (Generator等生成)
- build_encoder
- str2enc(TransformerEncoder等のへのマッピング)
-
build_base_model (Generator等生成)
- build_dataset_iter()(データセットのローダ)
-
build_trainer()(学習用コード)
- Trainer
-
train()
-
_gradient_accumulation()
- build_loss_compute (loss_computeの本体)
- NMTLossCompute(LossComputeBase)
-
_gradient_accumulation()
-
build_model(モデル生成器)
-
onmt.single_main.main
-
main()
- コーパス
- その他