エジンバラ大学神経機械翻訳システムnematus使用ノート
11788 ワード
*ブログアドレス:http://blog.csdn.net/wangxinginnlp/article/details/64921476
*step by step instructionがないため、コードにめまいがして、後で使うために説明ドキュメントを書きます.[注意、赤い字は穴だらけです]
コードの準備:
nematus https://github.com/rsennrich/nematus
subword-nmt https://github.com/rsennrich/subword-nmt
データの準備:
nematusには1000文の英独バイリンガル語彙(En-de)が付属している
実験環境:
nematusには構成が必要だと書かれています.
Nematus requires the following packages: Python >= 2.7 numpy Theano >= 0.7 (and its dependencies).
we recommend executing the following command in a Python virtual environment:
the following packages are optional, but highly recommended CUDA >= 7 (only GPU training is sufficiently fast) cuDNN >= 4 (speeds up training substantially)
you can run Nematus locally. To install it, execute
実験の疑問点:
1. なぜsource dictionariesが複数あるのですか?Linguistic Input Featuresをサポートし、Feautureごとにdictionary?
nematusは複数のsource dictionariesの転送をサポート
nmt.pyでsource dictionaryコードを受信:
train = TextIterator(datasets[0], datasets[1], dictionaries[:-1], dictionaries[-1],
....)
data_iterator.pyにTextIteratorがあります
self.source_dicts = []
for source_dict in source_dicts: self.source_dicts.append(load_dict(source_dict))
確かにそうです.READMEをよく読んでいません.
--dictionaries PATH [PATH ...] network vocabularies (one per source factor, plus target vocabulary)
*中国語と英語の練習語彙に中国語の部分に「|」の記号があり、そのまま掛けました.
w = [self.source_dicts[i][f] if f in self.source_dicts[i] else 1 for (i,f) in enumerate(w.split('|'))]
ここでwはinput unit、デフォルトはword、Linguistic Input Featuresの間は「|」で区切られています.
ステップ1:ファイルの解凍
**フォルダnematus-masterとsubword-nmt-masterは同じディレクトリの下にあります.
ステップ2:データ処理、用語集vocabularyの生成.
**独自のpreprocess.shスクリプト[スクリプトに問題があるようです]を使用して、バイリンガル語彙を処理します.
独自のpreprocess.shは:
しかし、上のPとP 1の2つは処理中に逆になったようです.
手動で書き換えることができます.
入力コマンド:./preprocess.sh./en de../test/data/corpus........./subword-nmt-master/
コマンド前のデータディレクトリを入力します.nematus-master/test/dataの下(システムに付属)ファイル:
入力コマンド処理中:
コマンド処理後のデータディレクトリを入力します.nematus-master/test/dataの下のファイル:
corpus.enはシステムに付属する語彙です
corpus.en.tokはtokenization後(perl $P/tokenizer.perl-threads 5-l$S<${P 1}.${S}>${P 1}.${S}.tok)の語料[持参語料は実はtoken過]
corpus.en.tok.bpeはsubword処理後の語彙です
corpus.en.tok.bpe.jsonはjson形式の英語(en)vocabulary
nematusは2つのストレージフォーマットのvocabularyをサポートし、nematus/util.pyで辞書を読み取る関数は次のとおりです.
ディクショナリフォーマット:1.jasonフォーマット[nematusスクリプト付きデフォルト生成]
2.pkl形式
ステップ3:モデルトレーニング
nematus-master/testに付属のtest_train.sh
パラメータはnematus-masterのREADME.mdで説明されています.最も重要なのは--datasets および --dictionariesパラメータは、訓練されたバイリンガル語彙とバイリンガル語彙にそれぞれ対応します.
持参した語彙は1000文しかないため,訓練反復は最大500回(--finish_afterパラメータ)であり,訓練はすぐに終了した.
トレーニングが終了すると、モデルはパラメータ(--model)パスの下に保存され、そのパスの下で生成されたファイルを観察します.
ステップ4:モデルテスト
test_translate.pyではsennrichが訓練したWMT 16 En->De En->Roモデルをネットからダウンロードする必要があります.このモデルをダウンロードしたくない場合は、手動でコードを変更します.
1.ダウンロードモデルを直接実行する
THEANO_FLAGS=mode=FAST_RUN,floatX=float32,device=gpu python test_translate.py
**En->Deモデルは615 MBあり、ダウンロードに時間がかかります.
En->Deモデルファイルを参照:http://data.statmt.org/rsennrich/wmt16_systems/de-en/
2.構成を変更し、自分がさっき走ったモデルを実行します.モデルのダウンロードコードの一部を注釈します.
コードがmodels/en-de/ディレクトリからmodel.npzファイルを読み取ることを発見し、models/en-de/ディレクトリを構築し、さっき訓練したmodel.npzコピーを入力します.
モデル.npz.jasonファイルが見つかりません.モデル.npz.jasonはモデルのプロファイルです.モデル.npzはモデルのパラメータです.
エラーを報告し続けます.model.npz.jasonではバイリンガル辞書のパスが間違っています.前のステップで保存したmodel.npz.jasonは相対パスの語彙表ファイルを記録しています.ディレクトリを切り替えましたが、このファイルが読めません.変更が必要です dictionaries:プロパティ.
しかし、さっきの訓練の語彙が少なかったため、モデルの訓練が悪かったので、復号された文はすべて「,」から構成されていた.
ステップ5:subwordリカバリ
TBD
ステップ6:翻訳パフォーマンス評価
TBD
*step by step instructionがないため、コードにめまいがして、後で使うために説明ドキュメントを書きます.[注意、赤い字は穴だらけです]
コードの準備:
nematus https://github.com/rsennrich/nematus
subword-nmt https://github.com/rsennrich/subword-nmt
データの準備:
nematusには1000文の英独バイリンガル語彙(En-de)が付属している
実験環境:
nematusには構成が必要だと書かれています.
Nematus requires the following packages:
we recommend executing the following command in a Python virtual environment:
pip install numpy numexpr cython tables theano
the following packages are optional, but highly recommended
you can run Nematus locally. To install it, execute
python setup.py install
実験の疑問点:
1. なぜsource dictionariesが複数あるのですか?Linguistic Input Featuresをサポートし、Feautureごとにdictionary?
nematusは複数のsource dictionariesの転送をサポート
nmt.pyでsource dictionaryコードを受信:
train = TextIterator(datasets[0], datasets[1], dictionaries[:-1], dictionaries[-1],
....)
data_iterator.pyにTextIteratorがあります
self.source_dicts = []
for source_dict in source_dicts: self.source_dicts.append(load_dict(source_dict))
確かにそうです.READMEをよく読んでいません.
--dictionaries PATH [PATH ...] network vocabularies (one per source factor, plus target vocabulary)
*中国語と英語の練習語彙に中国語の部分に「|」の記号があり、そのまま掛けました.
w = [self.source_dicts[i][f] if f in self.source_dicts[i] else 1 for (i,f) in enumerate(w.split('|'))]
ここでwはinput unit、デフォルトはword、Linguistic Input Featuresの間は「|」で区切られています.
ステップ1:ファイルの解凍
**フォルダnematus-masterとsubword-nmt-masterは同じディレクトリの下にあります.
ステップ2:データ処理、用語集vocabularyの生成.
**独自のpreprocess.shスクリプト[スクリプトに問題があるようです]を使用して、バイリンガル語彙を処理します.
独自のpreprocess.shは:
#!/bin/bash
P=$1
# source language (example: fr)
S=$2
# target language (example: en)
T=$3
# path to nematus/data
P1=$4
# path to subword NMT scripts (can be downloaded from https://github.com/rsennrich/subword-nmt)
P2=$5
# tokenize
perl $P1/tokenizer.perl -threads 5 -l $S < {P}.${S} > {P}.${S}.tok
perl $P1/tokenizer.perl -threads 5 -l $T < {P}.${T} > {P}.${T}.tok
# learn BPE on joint vocabulary:
cat {P}.${S}.tok {P}.${T}.tok | python $P2/learn_bpe.py -s 20000 > ${S}${T}.bpe
python $P2/apply_bpe.py -c ${S}${T}.bpe < {P}.${S}.tok > {P}.${S}.tok.bpe
python $P2/apply_bpe.py -c ${S}${T}.bpe < {P}.${T}.tok > {P}.${T}.tok.bpe
# build dictionary
python $P1/build_dictionary.py {P}.${S}.tok.bpe
python $P1/build_dictionary.py {P}.${T}.tok.bpe
しかし、上のPとP 1の2つは処理中に逆になったようです.
手動で書き換えることができます.
#!/bin/bash
# ( )
P=$1
#
# source language (example: fr)
S=$2
#
# target language (example: en)
T=$3
#
# path to nematus/data
P1=$4
# subword
# path to subword NMT scripts (can be downloaded from https://github.com/rsennrich/subword-nmt)
P2=$5
# tokenization
# tokenize
perl $P/tokenizer.perl -threads 5 -l $S < ${P1}.${S} > ${P1}.${S}.tok
perl $P/tokenizer.perl -threads 5 -l $T < ${P1}.${T} > ${P1}.${T}.tok
# BPE
# learn BPE on joint vocabulary:
cat ${P1}.${S}.tok ${P1}.${T}.tok | python $P2/learn_bpe.py -s 20000 > ${S}${T}.bpe
# subword
python $P2/apply_bpe.py -c ${S}${T}.bpe < ${P1}.${S}.tok > ${P1}.${S}.tok.bpe
python $P2/apply_bpe.py -c ${S}${T}.bpe < ${P1}.${T}.tok > ${P1}.${T}.tok.bpe
# subword
# build dictionary
python $P/build_dictionary.py ${P1}.${S}.tok.bpe
python $P/build_dictionary.py ${P1}.${T}.tok.bpe
入力コマンド:./preprocess.sh./en de../test/data/corpus........./subword-nmt-master/
コマンド前のデータディレクトリを入力します.nematus-master/test/dataの下(システムに付属)ファイル:
入力コマンド処理中:
コマンド処理後のデータディレクトリを入力します.nematus-master/test/dataの下のファイル:
corpus.enはシステムに付属する語彙です
corpus.en.tokはtokenization後(perl $P/tokenizer.perl-threads 5-l$S<${P 1}.${S}>${P 1}.${S}.tok)の語料[持参語料は実はtoken過]
corpus.en.tok.bpeはsubword処理後の語彙です
corpus.en.tok.bpe.jsonはjson形式の英語(en)vocabulary
nematusは2つのストレージフォーマットのvocabularyをサポートし、nematus/util.pyで辞書を読み取る関数は次のとおりです.
def load_dict(filename):
try:
with open(filename, 'rb') as f:
return unicode_to_utf8(json.load(f))
except:
with open(filename, 'rb') as f:
return pkl.load(f)
ディクショナリフォーマット:1.jasonフォーマット[nematusスクリプト付きデフォルト生成]
2.pkl形式
ステップ3:モデルトレーニング
nematus-master/testに付属のtest_train.sh
#!/bin/bash
# warning: this test is useful to check if training fails, and what speed you can achieve
# the toy datasets are too small to obtain useful translation results,
# and hyperparameters are chosen for speed, not for quality.
# For a setup that preprocesses and trains a larger data set,
# check https://github.com/rsennrich/wmt16-scripts/tree/master/sample
mkdir -p models
../nematus/nmt.py \
--model models/model.npz \
--datasets data/corpus.en data/corpus.de \
--dictionaries data/vocab.en.json data/vocab.de.json \
--dim_word 256 \
--dim 512 \
--n_words_src 30000 \
--n_words 30000 \
--maxlen 50 \
--optimizer adam \
--lrate 0.0001 \
--batch_size 40 \
--no_shuffle \
--dispFreq 500 \
--finish_after 500
パラメータはnematus-masterのREADME.mdで説明されています.最も重要なのは--datasets および --dictionariesパラメータは、訓練されたバイリンガル語彙とバイリンガル語彙にそれぞれ対応します.
持参した語彙は1000文しかないため,訓練反復は最大500回(--finish_afterパラメータ)であり,訓練はすぐに終了した.
トレーニングが終了すると、モデルはパラメータ(--model)パスの下に保存され、そのパスの下で生成されたファイルを観察します.
ステップ4:モデルテスト
test_translate.pyではsennrichが訓練したWMT 16 En->De En->Roモデルをネットからダウンロードする必要があります.このモデルをダウンロードしたくない場合は、手動でコードを変更します.
1.ダウンロードモデルを直接実行する
THEANO_FLAGS=mode=FAST_RUN,floatX=float32,device=gpu python test_translate.py
**En->Deモデルは615 MBあり、ダウンロードに時間がかかります.
En->Deモデルファイルを参照:http://data.statmt.org/rsennrich/wmt16_systems/de-en/
2.構成を変更し、自分がさっき走ったモデルを実行します.モデルのダウンロードコードの一部を注釈します.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os
import unittest
import requests
sys.path.append(os.path.abspath('../nematus'))
from translate import main as translate
def load_wmt16_model(src, target):
path = os.path.join('models', '{0}-{1}'.format(src,target))
try:
os.makedirs(path)
except OSError:
pass
for filename in ['model.npz', 'model.npz.json', 'vocab.{0}.json'.format(src), 'vocab.{0}.json'.format(target)]:
if not os.path.exists(os.path.join(path, filename)):
r = requests.get('http://data.statmt.org/rsennrich/wmt16_systems/{0}-{1}/'.format(src,target) + filename, stream=True)
with open(os.path.join(path, filename), 'wb') as f:
for chunk in r.iter_content(1024**2):
f.write(chunk)
class TestTranslate(unittest.TestCase):
"""
Regression tests for translation with WMT16 models
"""
'''
def setUp(self):
"""
Download pre-trained models
"""
#print '-------------'
load_wmt16_model('en','de')
load_wmt16_model('en','ro')
'''
def outputEqual(self, output1, output2):
"""given two translation outputs, check that output string is identical,
and probabilities are equal within rounding error.
"""
for i, (line, line2) in enumerate(zip(open(output1).readlines(), open(output2).readlines())):
if not i % 2:
self.assertEqual(line, line2)
else:
probs = map(float, line.split())
probs2 = map(float, line.split())
for p, p2 in zip(probs, probs2):
self.assertAlmostEqual(p, p2, 5)
# English-German WMT16 system, no dropout
def test_ende(self):
os.chdir('models/en-de/')
translate(['model.npz'], open('../../en-de/in'), open('../../en-de/out','w'), k=12, normalize=True, n_process=1, suppress_unk=True, print_word_probabilities=True)
os.chdir('../..')
self.outputEqual('en-de/ref','en-de/out')
'''
# English-Romanian WMT16 system, dropout
def test_enro(self):
os.chdir('models/en-ro/')
translate(['model.npz'], open('../../en-ro/in'), open('../../en-ro/out','w'), k=12, normalize=True, n_process=1, suppress_unk=True, print_word_probabilities=True)
os.chdir('../..')
self.outputEqual('en-ro/ref','en-ro/out')
'''
if __name__ == '__main__':
unittest.main()
コードがmodels/en-de/ディレクトリからmodel.npzファイルを読み取ることを発見し、models/en-de/ディレクトリを構築し、さっき訓練したmodel.npzコピーを入力します.
モデル.npz.jasonファイルが見つかりません.モデル.npz.jasonはモデルのプロファイルです.モデル.npzはモデルのパラメータです.
エラーを報告し続けます.model.npz.jasonではバイリンガル辞書のパスが間違っています.前のステップで保存したmodel.npz.jasonは相対パスの語彙表ファイルを記録しています.ディレクトリを切り替えましたが、このファイルが読めません.変更が必要です dictionaries:プロパティ.
しかし、さっきの訓練の語彙が少なかったため、モデルの訓練が悪かったので、復号された文はすべて「,」から構成されていた.
ステップ5:subwordリカバリ
TBD
ステップ6:翻訳パフォーマンス評価
TBD