[PYTHON] Essayons la traduction automatique neuronale avec Transformer

Je m'appelle okayu et j'étudie la traduction automatique à Nara. Comme le titre l'indique, faisons de la traduction automatique neuronale anglais-japonais à partir de zéro.

Qu'est-ce que la traduction automatique neuronale?

Fait référence à toutes les méthodes de traduction automatique utilisant le deep learning. Transformer est un modèle bien connu de la méthode de traduction automatique qui est actuellement courante.

Cette fois, j'aimerais faire de la traduction automatique neuronale anglais-japonais en utilisant ce modèle Transformer! Utilisez Sentenecepiece, OpenNMT, MeCab, multi-bleu.perl. Il est censé être appris sur un seul GPU. Cet article n'explique pas les technologies telles que Transformer ...

Flux de traduction automatique neuronale

Le flux général est le suivant

  1. [Préparer les données](# anchor0)
  2. [Prétraitement](# anchor2)
  3. [Apprentissage](# anchor3)
  4. [Traduire](# anchor4)
  5. [Détoniser](# anchor5)
  6. [Word Split](# anchor6)
  7. [Évaluation](# anchor7)

Comme OpenNMT-py est utilisé cette fois, l'environnement est python3.5 ou version ultérieure, PyTorch 1.4.

Préparons les données

Un corpus est une donnée linguistique utilisée dans le traitement du langage naturel. Un ensemble de données composé de brevets japonais et anglais appelés ASPEC et KFTT /kftt/index-ja.html) et JParaCrawl sont actuellement fournis gratuitement à des fins de recherche. Le contenu des autres corpus peut être trouvé sur la page ici du Dr Graham Neubig. En plus du japonais et de l'anglais, il existe des corpus tels que ParaCrawl.

Tout d'abord, préparons un ensemble de données de phrases bilingues pour l'apprentissage. Ce dont vous avez besoin est le suivant.

--train.ja --Texte japonais pour le train --train.fr --Texte anglais pour le train --dev.ja --Texte japonais pour validation --dev.en - Texte anglais pour validation --test.ja - Phrase japonaise pour test --test.fr --Anglais pour test

Puisqu'il s'agit d'une traduction anglais-japonais, test.ja est le texte de référence et test.en est le texte original. Train.ja, train.en, dev.ja, dev.en sont utilisés pour l'apprentissage. Les fichiers .en et .ja ont respectivement les mêmes lignes et traductions.

À titre d'exemple concret, ASPEC fournit des phrases bilingues pour le train, la validation (développement) et le test.

 B-94A0894379 ||| 3 |||Puisque l'opération côté utilisateur est importante pour le support des idées dans le développement matériel, une interface pour la manipulation matérielle au niveau atomique a été développée [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.

L'ID de l'article, les phrases bilingues japonaises et anglaises sont résumés sur une seule ligne. Il y a 1 million de phrases de ce type dans train1.txt, 1790 phrases dans dev.txt et 1812 phrases dans test.txt. Il ne peut pas être utilisé pour apprendre tel quel, il est nécessaire de le diviser en un ensemble de données en anglais et un ensemble de données en japonais uniquement. (Dans cet exemple, train1.txt est divisé en train.ja et train.en, dev.txt est divisé en dev.ja et dev.en, et test.txt est divisé en test.ja et test.en) À ce stade, assurez-vous que les lignes et les traductions correspondent dans les fichiers .en et .ja.

Prétraitement

Tokenize

Tokenize en utilisant Sentencepiece. J'utilise parfois MeCab et KyTea, mais cette fois le mot Tokenize en unités de sous-mots au lieu d'unités. Cette fois, le nombre de vocabulaire est de 16 000, et le vocabulaire est partagé en anglais et en japonais. Cat train.en train.ja> tmp.txt crée temporairement des données de phrase comprenant des données de train en anglais et en japonais.

De python

Installez avec pip install phrasepiece. Ensuite, nous étudierons avec le morceau de phrase.

spm_train.py


import sentencepiece as spm
sp = spm.SentencePieceProcessor()
spm.SentencePieceTrainer.Train("--input=tmp.txt --model_prefix=spm_trained_model --vocab_size=16000")

Exécutez (python spm_train.py) pour apprendre. spm_trained_model.model et spm_trained_model.vocab sont créés. Puisque tmp.txt n'est plus utilisé, supprimez-le. Tokenize tous les ensembles de données bilingues. (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 a été créé. (Je n'utilise pas test.ja.atok avec OpenNMT, mais je l'ai utilisé avec fairseq, donc je l'ai créé pour le moment) Veuillez vous référer au github officiel pour savoir comment le faire à partir de la ligne de commande. (Sentencepiece / GitHub)

Sérialisation

Cette fois, nous étudierons l'utilisation de OpenNMT. Outre OpenNMT, il existe fairseq. OpenNMT et fairseq effectuent tous deux un prétraitement unique. Convertit une instruction en une structure de données facile à apprendre.

ʻInstallez OpenNMT-py`.

git clone https://github.com/OpenNMT/OpenNMT-py.git
cd OpenNMT-py
python setup.py install

A partir de maintenant, on suppose que tout le traitement est effectué dans le répertoire ʻOpenNMT-py. Ensuite, sérialisez avec preprocess.py`. Puisqu'il s'agit d'une traduction anglais-japonais, spécifiez le jeu de données anglais pour src et le jeu de données japonais pour tgt.

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

Une fois exécutés, les fichiers preprocessed_dataset.train.pt, preprocessed_dataset.valid.pt et preprocessed_dataset.vocab.pt seront créés. (Un multiple sera créé en fonction de la quantité de données) L'explication de chaque donnée est la suivante. (Cité du GitHub officiel)

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

Apprentissage

Apprenez avec la commande suivante (citation: OpenNMTFAQ). Veuillez vous référer au Document officiel (anglais) pour l'explication des hyper paramètres. Comme l'apprentissage est effectué avec un seul GPU, le périphérique CUDA est spécifié et world_size est défini sur 1.

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 

Lorsque vous l'exécutez, cela commence comme ça. NMTModel (Puisque la structure du modèle est affichée, elle est un peu longue, je vais donc l'omettre.

[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(

C'est la preuve que l'apprentissage progresse au fur et à mesure que Step progresse de cette manière (l'exemple suivant efface un peu la valeur numérique)

[2020-06-18 00:59:56,869 INFO] Step 100/200000; acc:  *; ppl:  *; xent: *; lr: *; 12933/10876 tok/s; 122958 sec

Quand c'est fini, ça ressemble à ça

[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

L'apprentissage sera terminé en 1 à 2 jours avec un jeu de données ASPEC et un seul GPU. (GPU, le processeur est plus lent)

Traduction

Après l'apprentissage, des points de contrôle tels que save_model_name_step_200000.pt seront générés. Utilisez ceci pour traduire. Pour le texte original (texte anglais que vous souhaitez traduire), utilisez le tokenisé test.en.atok que vous avez créé précédemment. (test.en n'est pas bon)

python translate.py -model save_model_name_step_200000.pt -src test.en.atok -output output.txt -replace_unk -verbose -gpu 0

Le fichier de phrases traduites ʻoutput.txt` a été créé!

Détoniser

Le texte traduit ʻoutput.txt est tokenisé, alors détachez-le avec le Phrasepiece et renvoyez-le au texte brut. (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()

Vous avez maintenant une traduction japonaise brute ʻoutput.txt.detok`! C'est le flux de base de la traduction automatique neuronale. Ci-dessous, nous expliquerons comment le texte généré est évalué.

Partage de mots

Comme nous le verrons plus loin, BLEU, qui est basé sur la similitude du chevauchement de mots par ngram, est utilisé pour l'évaluation. Contrairement à l'anglais, le japonais n'inclut pas de blancs dans les phrases, il est donc nécessaire de diviser les mots. Cette fois, j'utiliserai MeCab pour la division des mots. (KyTea Certaines personnes semblent l'utiliser)

Installez le dictionnaire et MeCab selon cette procédure. Ensuite, utilisez python mecab_owakati.py output.txt.detok et python mecab_owakati.py test.ja pour diviser la traduction générée et les phrases de référence en mots.

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()

La traduction japonaise divisée par mot ʻoutput.txt.detok.mecab La phrase de référence divisée par mot test.ja.mecab` a été générée. Ensuite, nous évaluerons le texte traduit généré à l'aide de ceux-ci.

Évaluation

BLEU est souvent utilisé dans l'évaluation de la traduction automatique, nous allons donc l'utiliser pour l'évaluation.

Ces dernières années, des méthodes d'évaluation basées sur BERT ont émergé au lieu de BLEU (comme le score BERT?), Et il existe également des échelles d'évaluation telles que RIBES et ROUGE. Cette fois, je vais utiliser BLEU tranquillement. Utilisez multi-bleu.perl pour l'évaluation. Lorsque vous clonez OpenNMT-py, il se trouve par défaut dans le répertoire tools /.

Si vous exécutez perl tools / multi-bleu.perl test.ja.mecab <output.txt.detok.mecab, la valeur de BLEU sera affichée.

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)

En passant, le résultat de l'évaluation par WAT est répertorié dans ici. Si c'est l'hyper paramètre ci-dessus dans ASPEC, je pense que c'est BLEU38-40?. (Cela dépend beaucoup des hyper paramètres lors de l'apprentissage) Par rapport à cela, je pensais qu'une certaine société N et un certain N | CT sont plus forts. Aussi, bien que j'aie utilisé multi-bleu.perl cette fois, je pense que vous pouvez utiliser sacreBLEU. Récemment, j'ai commencé à soutenir le japonais. (Mecab uniquement)

finalement

Je ne savais pas quoi faire lors de la traduction automatique, alors je l'ai écrit pour des personnes qui n'ont jamais fait de traduction automatique (je n'ai pas d'articles en japonais et je ne suis pas bon en anglais) J'ai eu du mal). Je suis désolé si c'est difficile à comprendre. Nous espérons que vous serez autant que possible intéressé par le traitement du langage naturel et la traduction automatique.

Si vous êtes intéressé par des modèles autres que Transformer, il peut être amusant d'essayer fairseq. Divers sont mis en œuvre. Si vous avez des suggestions ou des opinions, n'hésitez pas à nous contacter. S'il y a un problème, effacez-le.

~~ Je l'ai fait depuis la ligne de commande ces derniers temps, mais quand je n'ai rien compris, je l'ai exécuté avec python ... ignorance ... ~~

Recommended Posts

Essayons la traduction automatique neuronale avec Transformer
Natural Language: Machine Translation Part2 - Transformateur de traduction automatique neurale
Essayez d'utiliser TensorFlow-Part 2-Convolution Neural Network (MNIST)
Essayez d'utiliser docker-py
Apprentissage par renforcement 10 Essayez d'utiliser un réseau neuronal formé.
Essayez d'utiliser Cookiecutter
Essayez d'utiliser PDFMiner
Essayez d'utiliser Selenium
Essayez d'utiliser scipy
Essayez d'utiliser pandas.DataFrame
Essayons la détection d'objets en temps réel en utilisant Faster R-CNN
Essayez d'utiliser matplotlib
Essayez d'utiliser PyODE
Essayez d'utiliser le bloc-notes Jupyter à partir d'Azure Machine Learning
Une introduction approximative à la bibliothèque de traduction automatique neuronale
Essayons la Wikification ~ Extraction d'informations à l'aide de Wikipedia et désambiguïsation ~
[Apprentissage automatique] Essayez de détecter des objets à l'aide de la recherche sélective
[Apprentissage automatique] Classification de texte à l'aide du modèle Transformer (classificateur basé sur l'attention)
[Azure] Essayez d'utiliser Azure Functions
Essayez d'utiliser virtualenv maintenant
Essayez d'utiliser W & B
Essayez d'utiliser Django templates.html
[Kaggle] Essayez d'utiliser LGBM
Essayez d'utiliser Tkinter de Python
Essayez d'utiliser Tweepy [Python2.7]
Essayez d'utiliser collate_fn de Pytorch
Essayez de créer un réseau de neurones en Python sans utiliser de bibliothèque