Transferência de Conhecimento e Tradução Automática Neural na Prática

A Tradução Automática Neural (NMT) está se desenvolvendo muito rapidamente. Hoje, para montar seu tradutor, você não precisa ter dois estudos superiores. Mas, para treinar o modelo, você precisa de um corpus paralelo grande (um corpus no qual a tradução no idioma de origem está associada à sentença). Na prática, estamos falando de pelo menos um milhão de pares de frases. Existe até uma grande área separada do FMI que explora métodos para o ensino de pares de idiomas com uma pequena quantidade de dados eletrônicos (English Low Resource NMT).

Estamos coletando o corpo russo-chuvash e, ao mesmo tempo, analisando o que pode ser feito com o volume de dados disponível. Neste exemplo, um caso de 90.000 pares de frases foi usado. O melhor resultado no momento foi dado pelo método de transferência de conhecimento (Eng. Transfer Learning), e será discutido no artigo. O objetivo do artigo é dar um exemplo prático de implementação que pode ser facilmente reproduzido.

O plano de treinamento é o seguinte. Precisamos pegar um prédio grande (pai), treinar um modelo neural nele e depois treinar nosso modelo filha. Além disso, o idioma alvo da tradução será o mesmo: russo. Intuitivamente, isso pode ser comparado ao aprendizado de um segundo idioma. É mais fácil aprender, conhecendo uma língua estrangeira. Também parece estudar uma área estreita de uma língua estrangeira, por exemplo, a terminologia médica da língua inglesa: primeiro você precisa aprender inglês em geral.

Como um corpo parental, tentamos tomar 1 milhão de pares de sentenças do corpo paralelo inglês-russo e 1 milhão do corpo cazaque-russo . Existem 5 milhões de frases nos dados do Cazaque. Desses, apenas aqueles com um coeficiente de conformidade (terceira coluna) superior a 2. A versão cazaque apresentou resultados um pouco melhores. Parece intuitivamente que isso seja compreensível, pois as línguas chuvash e cazaque são mais parecidas entre si. Mas, na verdade, isso não está comprovado e também depende muito da qualidade do caso. Mais detalhes sobre a seleção do corpo dos pais podem ser encontrados neste artigo . Sobre o corpo subsidiário de 90.000 pares de ofertas, você pode descobrir e solicitar dados de amostra aqui.

Agora para o código. Se você não possui sua própria placa gráfica rápida, você pode treinar o modelo no site da Colab . Para o treinamento, usamos a biblioteca Sockeye . Supõe-se que o Python3 já esteja instalado.

pip install sockeye 

Você também pode precisar mexer em separado com o MXNet , responsável por trabalhar com a placa de vídeo. O Colab precisa de instalação adicional da biblioteca

 pip install mxnet-cu100mkl 

Sobre as redes neurais, geralmente é aceito que basta alimentar os dados como estão, e eles descobrirão isso. Mas, na realidade, esse nem sempre é o caso. Portanto, no nosso caso, o corpo precisa ser pré-processado. Primeiro, a tokenizamos para que seja mais fácil para os modelos entenderem que "gato!" E "gato" são praticamente a mesma coisa. Por exemplo, apenas um tokenizer python serve.

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

Como resultado, alimentamos pares de frases no formulário

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

e

      .  , ,       , ,    ,        . 

A saída são as seguintes ofertas tokenizadas:

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

e em russo

       .   ,  ,        ,  ,     ,         . 

No nosso caso, precisaremos dos dicionários combinados dos casos pai e filho, para criar arquivos comuns:

 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 

uma vez que o treinamento adicional do modelo filho ocorre no mesmo dicionário.

Agora, uma digressão pequena, mas importante. No MP, as frases são divididas em átomos na forma de palavras e depois operam nas frases como sequências de palavras. Mas isso geralmente não é suficiente, porque uma cauda enorme é formada a partir das palavras que ocorrem no corpus uma vez. Construir um modelo probabilístico para eles é difícil. Isto é especialmente verdade para idiomas com morfologia desenvolvida (caso, sexo, número). O russo e o chuvash são exatamente esses idiomas. Mas existe uma solução. Você pode dividir a frase em um nível inferior, em subpalavras. Usamos a codificação de pares de bytes.

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

Temos aproximadamente essas seqüências de subpalavras

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

e

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

Pode-se ver que os afixos são bem diferenciados das palavras: @@ por um longo tempo e bom @@.
Para fazer isso, prepare dicionários 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 

E aplique-os aos tokens, por exemplo:

 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 

Por analogia, você precisa fazer para todos os arquivos: treinamento, validação e teste de modelos pai e filho.

Agora nos voltamos diretamente para o treinamento do modelo neural. Primeiro, você precisa preparar dicionários gerais de modelo:

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

Em seguida, treine o modelo pai. Um exemplo simples é descrito em mais detalhes na página Sockeye. Tecnicamente, o processo consiste em duas etapas: preparação de dados usando dicionários de modelo criados anteriormente

 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 

e o próprio aprendizado

 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 

O treinamento nas instalações da Colab leva cerca de um dia. Quando o treinamento do modelo estiver concluído, você poderá traduzi-lo para

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

Para treinar o modelo filho
 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 

O código de início do treinamento é semelhante a este

 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 

São adicionados parâmetros que indicam que a configuração e os pesos do modelo pai devem ser usados ​​como ponto de partida. Detalhes no exemplo com a reciclagem do Sockeye . Aprender um modelo infantil converge em cerca de 12 horas.

Para resumir, compare os resultados. O modelo usual de tradução automática produziu 24,96 BLEU de qualidade, enquanto o modelo de transferência de conhecimento foi de 32,38 BLEU. A diferença é visível também visualmente em exemplos de traduções. Portanto, enquanto continuamos a montar o gabinete, usaremos esse modelo.

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


All Articles