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.