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.