Transfert de connaissances et traduction automatique de neurones en pratique

La traduction automatique neuronale (NMT) se développe très rapidement. Aujourd'hui, pour assembler votre traducteur, vous n'avez pas besoin d'avoir deux formations supérieures. Mais pour former le modèle, vous avez besoin d'un grand corpus parallèle (un corpus dans lequel la traduction dans la langue source est associée à la phrase). En pratique, nous parlons d'au moins un million de paires de phrases. Il existe même un vaste domaine distinct du FMI qui explore les méthodes d'enseignement des paires de langues avec une petite quantité de données sous forme électronique (English Low Resource NMT).

Nous collectons le corps tchouvacho-russe et en même temps nous examinons ce qui peut être fait avec le volume de données disponible. Dans cet exemple, un cas de 90 000 paires d'offres a été utilisé. Le meilleur résultat pour le moment a été donné par la méthode de transfert des connaissances (Eng. Transfer Learning), et il sera discuté dans l'article. Le but de l'article est de donner un exemple pratique de mise en œuvre qui pourrait être facilement reproduit.

Le plan de formation est le suivant. Nous devons prendre un grand bâtiment (parent), former un modèle neuronal dessus, puis former notre modèle fille. De plus, la langue cible de la traduction sera la même: le russe. Intuitivement, cela peut être comparé à l'apprentissage d'une deuxième langue. Il est plus facile d'apprendre, en connaissant une langue étrangère. Cela ressemble également à l'étude d'une zone étroite d'une langue étrangère, par exemple, la terminologie médicale de la langue anglaise: vous devez d'abord apprendre l'anglais en général.

En tant que corps parental, ils ont essayé de prendre 1 million de paires de phrases du corps parallèle anglais-russe et 1 million du corps kazakh-russe . Il y a 5 millions de phrases dans les données kazakhes. Parmi ceux-ci, seuls ceux dont le coefficient de conformité (troisième colonne) était supérieur à 2. La version kazakhe a donné des résultats légèrement meilleurs. Il semble intuitivement que cela soit compréhensible, car les langues tchouvache et kazakhe se ressemblent davantage. Mais en fait, cela n'est pas prouvé, et dépend également grandement de la qualité du boîtier. Plus de détails sur la sélection de l'organe parental peuvent être trouvés dans cet article . À propos du corps subsidiaire de 90 000 paires d'offres, vous pouvez trouver et demander des exemples de données ici.

Passons maintenant au code. Si vous ne disposez pas de votre propre carte graphique rapide, vous pouvez entraîner le modèle sur le site Colab . Pour la formation, nous avons utilisé la bibliothèque Sockeye . Il est supposé que Python3 est déjà installé.

pip install sockeye 

Vous devrez peut-être également bricoler séparément avec MXNet , qui est chargé de travailler avec la carte vidéo. Colab a besoin d'une installation de bibliothèque supplémentaire

 pip install mxnet-cu100mkl 

Concernant les réseaux de neurones, il est généralement admis qu'il leur suffit de fournir les données telles quelles, et ils le découvriront. Mais en réalité ce n'est pas toujours le cas. Dans notre cas, le corps doit donc être prétraité. Tout d'abord, nous le symbolisons afin qu'il soit plus facile pour les modèles de comprendre que «chat!» Et «chat» sont à peu près la même chose. Par exemple, juste un tokenizer python fera l'affaire.

 from nltk.tokenize import WordPunctTokenizer def tokenize(src_filename, new_filename): with open(src_filename, encoding="utf-8") as src_file: with open(new_filename, "w", encoding="utf-8") as new_file: for line in src_file: new_file.write("%s" % ' '.join(WordPunctTokenizer().tokenize(line))) new_file.write("\n") 

En conséquence, nous alimentons des paires de phrases du formulaire

   ӗ  ҫ ӳ ӑӑ. ӑ ӑ ӑ ӑӗ, ӑ ӑӑӗ,   ӑ  ӗӗ -ӑ ӗӗҫ,  ҫӗ ӗ ӗҫ ӑӑ ӑӑ, ҫ ӗ ӗ   ӑ ӑ ӑӑ ӑ . 

et

      .  , ,       , ,    ,        . 

Le résultat est les offres tokenisées suivantes:

   ӗ  ҫ ӳ ӑӑ . ӑ ӑ ӑ ӑӗ , ӑ ӑӑӗ ,   ӑ  ӗӗ  - ӑ ӗӗҫ ,  ҫӗ ӗ ӗҫ ӑӑ ӑӑ , ҫ ӗ ӗ   ӑ ӑ ӑӑ ӑ  . 

et en russe

       .   ,  ,        ,  ,     ,         . 

Dans notre cas, nous aurons besoin des dictionnaires combinés des cas parent et enfant, nous allons donc créer des fichiers communs:

 cp kk.parent.train.tok kkchv.all.train.tok cat chv.child.train.tok >> kk.parent.train.tok cp ru.parent.train.tok ru.all.train.tok cat ru.child.train.tok >> ru.all.train.tok 

puisque la formation continue du modèle enfant a lieu sur le même dictionnaire.

Maintenant une petite mais importante digression. En MP, les phrases sont divisées en atomes sous forme de mots, puis opèrent sur des phrases comme des séquences de mots. Mais cela ne suffit généralement pas, car une énorme queue est formée à partir des mots qui se produisent une fois dans le corpus. Construire un modèle probabiliste pour eux est difficile. Cela est particulièrement vrai pour les langues à morphologie développée (cas, sexe, nombre). Le russe et le tchouvache ne sont que de telles langues. Mais il y a une solution. Vous pouvez diviser la phrase en un niveau inférieur, en sous-mots. Nous avons utilisé le codage par paire d'octets.

 git clone https://github.com/rsennrich/subword-nmt.git 

Nous obtenons approximativement de telles séquences de sous-mots

 @@   ӗ  ҫ ӳ@@  ӑӑ . @@ ӑ ӑ ӑ @@ ӑӗ , ӑ ӑӑ@@ ӗ ,   ӑ@@  @@  ӗӗ  - ӑ@@  ӗ@@ ӗҫ ,  ҫӗ@@  ӗ ӗҫ@@ @@  ӑӑ ӑӑ , ҫ@@ @@ @@  ӗ ӗ @@ @@  @@  ӑ ӑ ӑӑ ӑ  . 

et

 @@    @@  @@   . @@  @@ @@ @@ @@  , @@  , @@ @@  @@    @@  @@ @@  @@ @@ @@ @@  ,  ,  @@  @@ @@ @@  @@ @@ @@  ,       @@ @@  @@ @@ @@  . 

On peut voir que les affixes se distinguent bien des mots: pas @@ depuis longtemps et bon @@ ça.
Pour ce faire, préparez les dictionnaires bpe

 python subword-nmt/subword_nmt/learn_joint_bpe_and_vocab.py --input kkchv.all.train.tok ru.all.train.tok -s 10000 -o bpe.codes --write-vocabulary bpe.vocab.kkchv bpe.vocab.ru 

Et appliquez-les aux jetons, par exemple:

 python subword-nmt/subword_nmt/apply_bpe.py -c bpe.codes --vocabulary bpe.vocab.kkchv --vocabulary-threshold 50 < kkchv.all.train.tok > kkchv.all.train.bpe !python subword-nmt/subword_nmt/apply_bpe.py -c bpe.codes --vocabulary bpe.vocab.ru --vocabulary-threshold 50 < ru.all.train.tok > ru.all.train.bpe 

Par analogie, vous devez faire pour tous les fichiers: formation, validation et tester les modèles parent et enfant.

Nous passons maintenant directement à la formation du modèle neuronal. Vous devez d'abord préparer des dictionnaires de modèles généraux:

 python -m sockeye.prepare_data -s kk.all.train.bpe -t ru.all.train.bpe -o kkru_all_data 

Ensuite, entraînez le modèle parent. Un exemple simple est décrit plus en détail sur la page Sockeye. Techniquement, le processus comprend deux étapes: préparer les données à l'aide de dictionnaires de modèles créés précédemment

 python -m sockeye.prepare_data -s kk.parent.train.bpe -t ru.parent.train.bpe -o kkru_parent_data --source-vocab kkru_all_data/vocab.src.0.json --target-vocab kkru_all_data/vocab.trg.0.json 

et l'apprentissage lui-même

 python -m sockeye.train -d kkru_parent_data -vs kk.parent.dev.bpe -vt ru.parent.dev.bpe --encoder transformer --decoder transformer --transformer-model-size 512 --transformer-feed-forward-num-hidden 256 --transformer-dropout-prepost 0.1 --num-embed 512 --max-seq-len 100 --decode-and-evaluate 500 -o kkru_parent_model --num-layers 6 --disable-device-locking --batch-size 1024 --optimized-metric bleu --max-num-checkpoint-not-improved 10 

La formation dans les installations de Colab prend environ une journée. Une fois la formation du modèle terminée, vous pouvez la traduire avec

 python -m sockeye.translate --input kk.parent.test.bpe -m kkru_parent_model --output ru.parent.test_kkru_parent.bpe 

Former le modèle enfant
 python -m sockeye.prepare_data -s chv.child.train.bpe -t ru.child.train.bpe -o chvru_child_data --source-vocab kkru_all_data/vocab.src.0.json --target-vocab kkru_all_data/vocab.trg.0.json 

Le code de démarrage de la formation ressemble à ceci:

 python -m sockeye.train -d chvru_child_data -vs chv.child.dev.bpe -vt ru.child.dev.bpe --encoder transformer --decoder transformer --transformer-model-size 512 --transformer-feed-forward-num-hidden 256 --transformer-dropout-prepost 0.1 --num-embed 512 --max-seq-len 100 --decode-and-evaluate 500 -o ruchv_150K_skv_dev19_model --num-layers 6 --disable-device-locking --batch-size 1024 --optimized-metric bleu --max-num-checkpoint-not-improved 10 --config kkru_parent_model/args.yaml --params kkru_parent_model/params.best 

Des paramètres sont ajoutés qui indiquent que la configuration et les poids du modèle parent doivent être utilisés comme point de départ. Détails dans l'exemple avec recyclage du saumon rouge . L'apprentissage d'un modèle enfant converge en environ 12 heures.

Pour résumer, comparez les résultats. Le modèle de traduction automatique habituel a donné une qualité de 24,96 BLEU, tandis que le modèle de transfert de connaissances était de 32,38 BLEU. La différence est également visible visuellement sur des exemples de traductions. Par conséquent, pendant que nous continuons à assembler le boîtier, nous utiliserons ce modèle.

Source: https://habr.com/ru/post/fr475750/


All Articles