Mein Name ist okayu und ich studiere maschinelle Übersetzung in Nara. Lassen Sie uns, wie der Titel schon sagt, die englisch-japanische neuronale maschinelle Übersetzung von Grund auf neu durchführen.
Bezieht sich auf alle maschinellen Übersetzungsmethoden, die Deep Learning verwenden. Transformer ist ein bekanntes Modell der maschinellen Übersetzungsmethode, die derzeit der Mainstream ist.
Dieses Mal möchte ich mit diesem Transformer-Modell eine englisch-japanische neuronale maschinelle Übersetzung durchführen! Verwenden Sie Sentenecepiece, OpenNMT, MeCab, multi-bleu.perl. Es soll auf einer einzigen GPU gelernt werden. Dieser Artikel erklärt keine Technologien wie Transformer ...
Der allgemeine Fluss ist wie folgt
Da diesmal OpenNMT-py verwendet wird, ist die Umgebung python3.5 oder höher, PyTorch 1.4.
Ein Korpus sind Sprachdaten, die bei der Verarbeitung natürlicher Sprache verwendet werden. Ein Datensatz bestehend aus japanischen und englischen Patenten mit den Namen ASPEC und KFTT. /kftt/index-ja.html) und JParaCrawl werden derzeit zu Forschungszwecken kostenlos zur Verfügung gestellt. Der Inhalt anderer Korpora kann auf der Seite hier von Dr. Graham Neubig gefunden werden. Neben Japanisch und Englisch gibt es Korpora wie ParaCrawl.
Bereiten wir zunächst einen zweisprachigen Satzdatensatz für das Lernen vor. Was Sie brauchen, ist wie folgt.
--train.ja - Japanischer Text für den Zug --train.de --Englischer Text für den Zug --dev.ja - Japanischer Text zur Validierung --dev.de - Englischer Text zur Validierung --test.ja - Japanischer Satz für den Test --test.de --Englisch für Test
Da es sich um eine englisch-japanische Übersetzung handelt, ist test.ja der Referenztext und test.en der Originaltext. Train.ja, train.en, dev.ja, dev.en werden zum Lernen verwendet. Die .en- und .ja-Dateien haben die gleichen Zeilen bzw. Übersetzungen.
Als aktuelles Beispiel bietet ASPEC zweisprachige Sätze für Zug, Validierung (Entwicklung) und Test.
B-94A0894379 ||| 3 |||Da die Operation auf der Benutzerseite für die Ideenunterstützung bei der Materialentwicklung wichtig ist, wurde eine Schnittstelle für die Materialmanipulation auf atomarer Ebene entwickelt [1994.8].||| Because user operation is important for the idea support in material development, an interface for a substance operation at atomic level was developed.
Die Artikel-ID, japanische und englische Sätze, die parallel übersetzt werden, werden in einer Zeile zusammengefasst. Es gibt 1 Million solcher Sätze in train1.txt, 1790 Sätze in dev.txt und 1812 Sätze in test.txt. Es kann nicht zum Lernen verwendet werden, da es in einen Nur-Englisch-Datensatz und einen Nur-Japanisch-Datensatz unterteilt werden muss. (In diesem Beispiel ist train1.txt in train.ja und train.en unterteilt, dev.txt in dev.ja und dev.en und test.txt in test.ja und test.en.) Stellen Sie zu diesem Zeitpunkt sicher, dass die Zeilen und Übersetzungen in den Dateien .en und .ja übereinstimmen.
Tokenize mit Satzstück. Ich benutze manchmal MeCab und KyTea, aber diesmal das Wort Tokenize in Unterworteinheiten anstelle von Einheiten.
Dieses Mal beträgt die Anzahl der Vokabeln 16000, und das Vokabular wird auf Englisch und Japanisch geteilt. Cat train.en train.ja> tmp.txt
erstellt vorübergehend Satzdaten, einschließlich englischer und japanischer Zugdaten.
Installieren Sie mit "Pip Install Satzstück". Als nächstes werden wir mit dem Satzstück lernen.
spm_train.py
import sentencepiece as spm
sp = spm.SentencePieceProcessor()
spm.SentencePieceTrainer.Train("--input=tmp.txt --model_prefix=spm_trained_model --vocab_size=16000")
Führen Sie (python spm_train.py
) aus, um zu lernen. spm_trained_model.model
und spm_trained_model.vocab
werden erstellt. Da tmp.txt
nicht mehr verwendet wird, löschen Sie es.
Tokenisieren Sie alle zweisprachigen Datensätze. (python spm_tok.py
)
spm_tok.py
import sentencepiece as spm
sp = spm.SentencePieceProcessor()
sp.load('spm_trained_model.model')
def detok(filename, outputfilename):
f = open(filename, mode='r')
foutput = open(outputfilename, mode='w')
d = f.read()
d = d.split('\n')
for i in d:
data = sp.EncodeAsPieces(str(i))
data = ' '.join(data)
foutput.write(data + '\n')
f.close()
foutput.close()
detok('train.en','train.en.atok')
detok('train.ja','train.ja.atok')
detok('dev.en','dev.en.atok')
detok('dev.ja','dev.ja.atok')
detok('test.en','test.en.atok')
detok('test.ja','test.ja.atok')
Tokenized train.en.atok
, train.ja.atok
, dev.en.atok
, dev.ja.atok
, test.en.atok
, test.ja. atok
wurde erstellt.
(Ich benutze test.ja.atok nicht mit OpenNMT, aber ich habe es mit fairseq verwendet, also habe ich es vorerst erstellt.)
Informationen dazu finden Sie im offiziellen Github über die Befehlszeile. (Satzstück / GitHub)
Dieses Mal werden wir mit OpenNMT lernen. Neben OpenNMT gibt es fairseq. Sowohl OpenNMT als auch fairseq führen eine einzigartige Vorverarbeitung durch. Konvertiert eine Anweisung in eine Datenstruktur, die leicht zu erlernen ist.
Installieren Sie OpenNMT-py
.
git clone https://github.com/OpenNMT/OpenNMT-py.git
cd OpenNMT-py
python setup.py install
Angenommen, die gesamte Verarbeitung wird in Zukunft im Verzeichnis "OpenNMT-py" durchgeführt.
Als nächstes serialisieren Sie mit preprocess.py
. Da es sich um eine englisch-japanische Übersetzung handelt, geben Sie den englischen Datensatz für src und den japanischen Datensatz für tgt an.
python preprocess.py -train_src train.en.atok -train_tgt train.ja.atok -valid_src dev.en.atok -valid_tgt dev.ja.atok -save_data preprocessed_dataset
Bei der Ausführung werden die Dateien "preprocessed_dataset.train.pt", "preprocessed_dataset.valid.pt" und "preprocessed_dataset.vocab.pt" erstellt. (Je nach Datenmenge werden mehrere erstellt.) Die Erklärung der einzelnen Daten lautet wie folgt. (Zitiert aus dem offiziellen GitHub)
After running the preprocessing, the following files are generated:
- demo.train.pt: serialized PyTorch file containing training data
- demo.valid.pt: serialized PyTorch file containing validation data
- demo.vocab.pt: serialized PyTorch file containing vocabulary data
Lernen Sie mit dem folgenden Befehl (Zitat: OpenNMTFAQ). Weitere Informationen zu Hyperparametern finden Sie unter Offizielles Dokument (Englisch). Da das Lernen mit einer einzelnen GPU durchgeführt wird, wird das CUDA-Gerät angegeben und world_size auf 1 gesetzt.
export CUDA_VISIBLE_DEVICES=0 && \
python train.py -data preprocessed_dataset -save_model save_model_name \
-layers 6 -rnn_size 512 -word_vec_size 512 \
-transformer_ff 2048 -heads 8 -encoder_type transformer -decoder_type transformer -position_encoding \
-train_steps 200000 -max_generator_batches 2 -dropout 0.1 -batch_size 4096 -batch_type tokens \
-normalization tokens -accum_count 2 -optim adam -adam_beta2 0.998 -decay_method noam \
-warmup_steps 8000 -learning_rate 2 -max_grad_norm 0 -param_init 0 -param_init_glorot \
-label_smoothing 0.1 -valid_steps 10000 -save_checkpoint_steps 40000 -world_size 1 -gpu_ranks 0
Wenn Sie es ausführen, beginnt es so. NMTModel (Da die Modellstruktur angezeigt wird, ist sie etwas lang, daher werde ich sie weglassen.
[2020-06-16 14:50:34,141 INFO] * src vocab size = 8071
[2020-06-16 14:50:34,143 INFO] * tgt vocab size = 14921
[2020-06-16 14:50:34,145 INFO] Building model...
[2020-06-16 14:50:38,414 INFO] NMTModel(
Es ist ein Beweis dafür, dass das Lernen mit fortschreitendem Schritt auf diese Weise voranschreitet (im folgenden Beispiel wird der numerische Wert ein wenig gelöscht).
[2020-06-18 00:59:56,869 INFO] Step 100/200000; acc: *; ppl: *; xent: *; lr: *; 12933/10876 tok/s; 122958 sec
Wenn es vorbei ist, ist es so
[2020-06-18 01:01:23,330 INFO] Step 200000/200000; acc: *; ppl: *; xent: *; lr: *; 13220/10803 tok/s; 123045 sec
[2020-06-18 01:01:23,336 INFO] Loading dataset from preprocessed_dataset.valid.pt
[2020-06-18 01:01:23,473 INFO] number of examples: 1791
[2020-06-18 01:01:26,183 INFO] Validation perplexity: *
[2020-06-18 01:01:26,185 INFO] Validation accuracy: *
[2020-06-18 01:01:26,265 INFO] Saving checkpoint save_model_name_step_200000.pt
Das Lernen wird in 1 bis 2 Tagen mit ASPEC-Datensatz und einzelner GPU abgeschlossen. (GPU, CPU ist langsamer)
Nach dem Lernen werden Prüfpunkte wie "save_model_name_step_200000.pt" generiert. Verwenden Sie dies zum Übersetzen.
Verwenden Sie für den Originaltext (englischer Text, den Sie übersetzen möchten) das zuvor erstellte tokenisierte test.en.atok
. (test.en
ist nicht gut)
python translate.py -model save_model_name_step_200000.pt -src test.en.atok -output output.txt -replace_unk -verbose -gpu 0
Die übersetzte Satzdatei output.txt
wurde erstellt!
Der übersetzte Text "output.txt" ist mit einem Token versehen. Entschlüsseln Sie ihn daher mit dem Satz und kehren Sie zum Rohtext zurück. (python spm_detok.py
)
spm_detok.py
import sentencepiece as spm
import sys
sp = spm.SentencePieceProcessor()
sp.load('spm_trained_model.model')
openfile = 'output.txt'
f = open(openfile,mode='r')
data = f.read()
outputsentence = data.split('\n')
f.close()
f2 = open(openfile+'detok', mode='w')
for i in outputsentence:
i = i.split(' ')
tmp = sp.decode_pieces(i)
f2.write(tmp + '\n')
f2.close()
Jetzt haben Sie eine japanische Übersetzung des Rohtextes output.txt.detok
!
Dies ist der Grundfluss der neuronalen maschinellen Übersetzung. Im Folgenden wird erläutert, wie der generierte Text ausgewertet wird.
Wie wir später sehen werden, wird BLEU, das auf der Ähnlichkeit der Wortüberlappung durch ngram basiert, zur Bewertung verwendet. Im Gegensatz zu Englisch enthält Japanisch keine Leerzeichen in Sätzen, daher ist es notwendig, Wörter zu teilen. Dieses Mal werde ich MeCab für die Wortteilung verwenden. (KyTea Einige Leute scheinen es zu benutzen)
Installieren Sie das Wörterbuch und MeCab gemäß diesem Verfahren.
Verwenden Sie als Nächstes python mecab_owakati.py output.txt.detok
und python mecab_owakati.py test.ja
, um die generierten Übersetzungs- und Referenzsätze in Wörter zu unterteilen.
mecab_owakati.py
import MeCab
import sys
m = MeCab.Tagger('-Owakati')
openfile = sys.argv[1]
f = open(openfile,mode='r')
f2 = open(openfile+'.mecab', mode='w')
data = f.read()
f.close()
data = data.split('\n')
for i in data:
k = m.parse(i)
f2.write(k)
f2.close()
Wortgeteilte japanische Übersetzung output.txt.detok.mecab
Wortgeteilter Referenzsatz test.ja.mecab
wurde generiert. Als nächstes werden wir den übersetzten Text auswerten, der mit diesen generiert wurde.
BLEU wird häufig bei der Bewertung der maschinellen Übersetzung verwendet, daher werden wir es für die Bewertung verwenden.
In den letzten Jahren wurden BERT-basierte Bewertungsmethoden anstelle von BLEU (wie BERT-Score?) Entwickelt. Außerdem gibt es Bewertungsskalen wie RIBES und ROUGE. Dieses Mal werde ich BLEU leise verwenden. Verwenden Sie zur Auswertung multi-bleu.perl
. Wenn Sie OpenNMT-py klonen, befindet es sich standardmäßig im Verzeichnis tools /
.
Wenn Sie "perl tools / multi-bleu.perl test.ja.mecab <output.txt.detok.mecab" ausführen, wird der Wert von BLEU angezeigt.
BLEU = *, */*/*/* (BP=*, ratio=*, hyp_len=*, ref_len=*)
#BLEU = global-BLEU score, precisions of 1-grams/2-grams/3-grams/4-grams (BP=brevity penalty, ratio=length ratio, hyp_len=hypothesis length, ref_len=reference length)
Das Bewertungsergebnis von WAT ist übrigens in [hier] aufgeführt (http://lotus.kuee.kyoto-u.ac.jp/WAT/evaluation/index.html). Wenn es der obige Hyperparameter in ASPEC ist, denke ich, ist es BLEU38-40 ?. (Es hängt stark von den Hyperparametern beim Lernen ab.) Im Vergleich dazu dachte ich, dass eine bestimmte N-Firma und eine bestimmte N | CT stärker sind. Obwohl ich diesmal multi-bleu.perl verwendet habe, denke ich, dass Sie sacreBLEU verwenden können. Vor kurzem habe ich angefangen, Japanisch zu unterstützen. (Nur Mecab)
Ich wusste nicht, was ich tun sollte, wenn ich maschinelle Übersetzung mache, also schrieb ich es für Leute, die noch nie maschinelle Übersetzung gemacht haben (ich habe keine japanischen Artikel und ich bin nicht gut in Englisch) Ich hatte es schwer). Es tut mir leid, wenn es schwer zu verstehen ist. Wir hoffen, dass Sie sich so weit wie möglich für die Verarbeitung natürlicher Sprache und maschinelle Übersetzung interessieren.
Wenn Sie an anderen Modellen als Transformer interessiert sind, kann es Spaß machen, fairseq auszuprobieren. Verschiedene sind implementiert. Wenn Sie Anregungen oder Meinungen haben, zögern Sie bitte nicht, uns zu kontaktieren. Wenn es ein Problem gibt, löschen Sie es.
~~ Ich habe es in letzter Zeit über die Kommandozeile gemacht, aber als ich nichts verstand, habe ich es mit Python ausgeführt ... Unwissenheit ... ~~
Recommended Posts