ナード戦隊データマン

機械学習と自然言語処理についてのブログ

tensor2tensorで和英翻訳

tensor2tensor1とは、ディープラーニングをより使いやすく、ML研究を加速させるために設計されたモデルとデータセットを含んだライブラリです。

実行フロー

  1. パラレルコーパスをダウンロード。
  2. コーパスを分離。
  3. 独自のデータジェネレータを登録。
  4. データを生成。
  5. 訓練。
  6. 対話的に翻訳を実行。

コード

パラレルコーパスのダウンロード (wget)

Tatoeba Project2 から抽出されたデータ3があるので、これをダウンロードします。

wget http://www.manythings.org/anki/jpn-eng.zip
unzip jpn-eng.zip

コーパスの分離 (split.py)

コーパスを英語と日本語に分離しておきます。これにはあまり意味はありません。

if __name__ == "__main__":
    with open("./jpn.txt") as f, \
         open("tatoeba_jp.txt", "w") as f_jp, \
         open("tatoeba_en.txt", "w") as f_en:
        for line in f:
            line = line.strip()
            line = line.split("\t")
            f_en.write(line[0]+"\n")
            f_jp.write(line[1]+"\n")

独自のデータジェネレータを登録 (myproblem.py)

こちら4 を参考に、データジェネレータを登録します。

from tensor2tensor.data_generators import problem
from tensor2tensor.data_generators import text_problems
from tensor2tensor.utils import registry
 
 
@registry.register_problem
class Translate_JPEN(text_problems.Text2TextProblem):
    @property
    def approx_vocab_size(self):
        return 2**13
    
    @property
    def is_generate_per_split(self):
        return False
 
    @property
    def dataset_splits(self):
        return [{
            "split": problem.DatasetSplit.TRAIN,
            "shards": 9,
        }, {
            "split": problem.DatasetSplit.EVAL,
            "shards": 1,
        }]
 
    def generate_samples(self, data_dir, tmp_dir, dataset_split):
        filename_jp = './data/tatoeba_jp.txt'
        filename_en = './data/tatoeba_en.txt'
 
        with open(filename_jp) as f_jp, open(filename_en) as f_en:
            for src, tgt in zip(f_jp, f_en):
                src = src.strip()
                tgt = tgt.strip()
                if not src or not tgt:
                    continue
                yield {'inputs': src, 'targets': tgt}

同じディレクトリに以下の__init__.pyが必要だそうです。

from . import myproblem

データを生成 (t2t-datagen)

t2t-datagen --data_dir=data/data1 --tmp_dir=tmp --problem=translate_jpen --t2t_usr_dir .

訓練 (t2t-trainer)

t2t-trainer --data_dir=data/data1 --problem=translate_jpen --model=transformer --hparams_set=transformer_base_single_gpu --output_dir=training_result1 --t2t_usr_dir=.

対話的に翻訳を実行(t2t-decoder)

t2t-decoder --data_dir=data/data1 --problem=translate_jpen --model=transformer --hparams_set=transformer_base_single_gpu --output_dir=training_result1 --decode_hparams="beam_size=4,alpha=0.6" --decode_interactive=true --t2t_usr_dir=.

いくつかの結果

>今日はいい天気。
It's a nice day today.

>今日は晴れ。
It's fine today.

>おいしい卵。
It's delicious.

>足が痛い。
My leg hurts.

>私は病気が怖い。
I am afraid of being ill.

>朝のコーヒーは格別にうまい。
In the morning, a good cup of coffee.

>やあ元気?
How are you?

>俺は警察だ馬鹿野郎!
Fantastic!

考察

翻訳できている文とあまりできていない文があります。翻訳できていない文は、そもそも訓練データ内に当該の語彙がありません。

実用レベルで行うには、もっと巨大なコーパスが必要になるのかもしれません。今回試した方法だけでは未知語への対処は難しいと思います。

参考