Transferencia de conocimiento y traducción automática neuronal en la práctica

La traducción automática neuronal (NMT) se está desarrollando muy rápido. Hoy, para reunir a su traductor, no necesita tener dos estudios superiores. Pero para entrenar el modelo, necesita un corpus paralelo grande (un corpus en el que la traducción en el idioma de origen está asociada con la oración). En la práctica, estamos hablando de al menos un millón de pares de oraciones. Incluso hay una gran área separada del FMI que explora métodos de enseñanza de pares de idiomas con una pequeña cantidad de datos en forma electrónica (inglés NMT de bajos recursos).

Estamos recolectando el cuerpo Chuvash-Ruso y al mismo tiempo estamos viendo qué se puede hacer con el volumen de datos disponible. En este ejemplo, se utilizó un caso de 90,000 pares de oraciones. El mejor resultado en este momento fue dado por el método de transferencia de conocimiento (Ing. Transfer Learning), y será discutido en el artículo. El propósito del artículo es dar un ejemplo práctico de implementación que pueda reproducirse fácilmente.

El plan de entrenamiento es el siguiente. Necesitamos tomar un edificio grande (padre), entrenar un modelo neuronal en él y luego entrenar a nuestro modelo hija. Además, el idioma objetivo de traducción será el mismo: ruso. Intuitivamente, esto se puede comparar con el aprendizaje de un segundo idioma. Es más fácil aprender, saber un idioma extranjero. También parece estudiar un área estrecha de un idioma extranjero, por ejemplo, la terminología médica del idioma inglés: primero debes aprender inglés en general.

Como cuerpo parental, intentaron tomar 1 millón de pares de oraciones del cuerpo paralelo inglés-ruso y 1 millón del cuerpo kazajo-ruso . Hay 5 millones de oraciones en los datos kazajos. De estos, solo se tomaron aquellos con un coeficiente de cumplimiento (tercera columna) de más de 2. La versión kazaja dio resultados ligeramente mejores. Parece intuitivamente que esto es comprensible, ya que los idiomas Chuvash y Kazajo son más similares entre sí. Pero, de hecho, esto no está probado, y también depende en gran medida de la calidad del caso. Se pueden encontrar más detalles sobre la selección del cuerpo parental en este artículo . Sobre el cuerpo subsidiario de 90,000 pares de ofertas, puede averiguar y solicitar datos de muestra aquí.

Ahora al código. Si no tiene su propia tarjeta gráfica rápida, puede entrenar al modelo en el sitio de Colab . Para el entrenamiento, utilizamos la biblioteca Sockeye . Se supone que Python3 ya está instalado.

pip install sockeye 

También es posible que tenga que jugar por separado con MXNet , que es responsable de trabajar con la tarjeta de video. Colab necesita instalación de biblioteca adicional

 pip install mxnet-cu100mkl 

Con respecto a las redes neuronales, generalmente se acepta que es suficiente para que alimenten los datos tal como están, y lo resolverán. Pero en realidad este no es siempre el caso. Entonces, en nuestro caso, el cuerpo necesita ser preprocesado. Primero, lo tokenizamos para que sea más fácil para las modelos entender que "gato" y "gato" son casi lo mismo. Por ejemplo, solo bastará un tokenizador de Python.

 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 oraciones de la forma

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

y

      .  , ,       , ,    ,        . 

El resultado son las siguientes ofertas tokenizadas:

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

y en ruso

       .   ,  ,        ,  ,     ,         . 

En nuestro caso, necesitaremos los diccionarios combinados de los casos padre e hijo, por lo que crearemos archivos comunes:

 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 

dado que la formación adicional del modelo secundario se lleva a cabo en el mismo diccionario.

Ahora una pequeña pero importante digresión. En MP, las oraciones se dividen en átomos en forma de palabras y luego operan en oraciones como secuencias de palabras. Pero esto generalmente no es suficiente, porque una gran cola se forma a partir de las palabras que ocurren una vez en el corpus. Construir un modelo probabilístico para ellos es difícil. Esto es especialmente cierto para los idiomas con morfología desarrollada (caso, género, número). Tanto el ruso como el chuvash son solo esos idiomas. Pero hay una solución. Puede dividir la oración en un nivel inferior, en subpalabras. Utilizamos la codificación de pares de bytes.

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

Obtenemos aproximadamente tales secuencias de subpalabras

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

y

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

Se puede ver que los afijos se distinguen bien de las palabras: no @@ durante mucho tiempo y bueno @@ eso.
Para hacer esto, prepare diccionarios 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 

Y aplicarlos a tokens, por ejemplo:

 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 analogía, debe hacer para todos los archivos: capacitación, validación y prueba de modelos primarios y secundarios.

Ahora pasamos directamente al entrenamiento del modelo neural. Primero debe preparar diccionarios modelo generales:

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

Luego, entrene el modelo principal. Un ejemplo simple se describe con más detalle en la página de Sockeye. Técnicamente, el proceso consta de dos pasos: preparación de datos utilizando diccionarios modelo creados previamente

 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 

y el aprendizaje en sí

 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 capacitación en las instalaciones de Colab dura aproximadamente un día. Cuando se completa la capacitación de la modelo, puede traducirla con ella para que

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

Para entrenar al modelo infantil
 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 

El código de inicio de entrenamiento se ve así

 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 

Se agregan parámetros que indican que la configuración y los pesos del modelo principal deben usarse como punto de partida. Detalles en el ejemplo con reentrenamiento de Sockeye . El modelo de aprendizaje de un niño converge en aproximadamente 12 horas.

Para resumir, compare los resultados. El modelo habitual de traducción automática arrojó una calidad de 24.96 BLEU, mientras que el modelo de transferencia de conocimiento fue de 32.38 BLEU. La diferencia es visible también visualmente en ejemplos de traducciones. Por lo tanto, mientras continuamos armando el caso, utilizaremos este modelo.

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


All Articles