Modèles de séquence à séquence, partie 2

Bonjour Ă  tous!

La deuxième partie de la traduction, que nous avons publiée il y a quelques semaines, en préparation du lancement du deuxième volet du cours Data Scientist . En avant est un autre matériel intéressant et une leçon ouverte.

En attendant, nous sommes allés plus loin dans la jungle des mannequins.

Modèle de traduction neuronale

Bien que le cœur du modèle de séquence à séquence soit créé par des fonctions de tensorflow/tensorflow/python/ops/seq2seq.py , il existe encore quelques astuces utilisées dans notre modèle de traduction dans models/tutorials/rnn/translate/seq2seq_model.py , à propos de mérite d'être mentionné.



Softmax échantillonné et projection de sortie

Comme mentionné ci-dessus, nous voulons utiliser le softmax échantillonné pour travailler avec un grand dictionnaire de sortie. Pour en décoder, vous devez suivre la projection de la sortie. La perte de softmax échantillonnée et la projection de sortie sont générées par le code suivant dans seq2seq_model.py .

 if num_samples > 0 and num_samples < self.target_vocab_size: w_t = tf.get_variable("proj_w", [self.target_vocab_size, size], dtype=dtype) w = tf.transpose(w_t) b = tf.get_variable("proj_b", [self.target_vocab_size], dtype=dtype) output_projection = (w, b) def sampled_loss(labels, inputs): labels = tf.reshape(labels, [-1, 1]) # We need to compute the sampled_softmax_loss using 32bit floats to # avoid numerical instabilities. local_w_t = tf.cast(w_t, tf.float32) local_b = tf.cast(b, tf.float32) local_inputs = tf.cast(inputs, tf.float32) return tf.cast( tf.nn.sampled_softmax_loss( weights=local_w_t, biases=local_b, labels=labels, inputs=local_inputs, num_sampled=num_samples, num_classes=self.target_vocab_size), dtype) 

Tout d'abord, notez que nous ne créons un softmax échantillonné que si le nombre d'échantillons (512 par défaut) est inférieur à la taille cible du dictionnaire. Pour les dictionnaires inférieurs à 512, il est préférable d'utiliser la perte standard softmax.

Ensuite, créez une projection de la sortie. Il s'agit d'une paire composée d'une matrice de poids et d'un vecteur de déplacement. Lorsqu'elle est utilisée, la cellule rnn renvoie les vecteurs de forme du nombre d'échantillons d'apprentissage par size , et non le nombre d'échantillons d' target_vocab_size par target_vocab_size . Pour restaurer les logits, vous devez le multiplier par la matrice de poids et ajouter un décalage, ce qui se produit aux lignes 124-126 dans seq2seq_model.py .

 if output_projection is not None: for b in xrange(len(buckets)): self.outputs[b] = [tf.matmul(output, output_projection[0]) + output_projection[1] for ...] 

Godet et rembourrage

En plus du softmax échantillonné, notre modèle de traduction utilise également le bucketing , une méthode qui vous permet de gérer efficacement des phrases de différentes longueurs. Pour commencer, expliquez le problème. Lors de la traduction de l'anglais vers le français, nous avons des phrases anglaises de différentes longueurs L1 à l'entrée et des phrases françaises de différentes longueurs L2 à la sortie. Étant donné que la phrase anglaise est transmise sous forme d' encoder_inputs et que la phrase française est affichée sous forme d' decoder_inputs (avec le préfixe de symbole GO), il est nécessaire de créer un modèle seq2seq pour chaque paire (L1, L2 + 1) de longueurs de phrases anglais et français. En conséquence, nous obtenons un énorme graphique composé de nombreux sous-graphiques similaires. D'un autre côté, nous pouvons «compléter» chaque phrase avec des caractères PAD spéciaux. Et puis nous n'avons besoin que d'un seul modèle seq2seq pour les longueurs "compactes". Mais un tel modèle sera inefficace en courtes phrases - vous devez encoder et décoder beaucoup de caractères PAD inutiles.

Comme compromis entre la création d'un graphique pour chaque paire de longueurs et le remplissage à une seule longueur, nous utilisons un certain nombre de compartiments et remplissons chaque phrase à la longueur du groupe ci-dessus. Dans translate.py nous utilisons les groupes suivants par défaut.

 buckets = [(5, 10), (10, 15), (20, 25), (40, 50)] 


Ainsi, si une phrase anglaise avec 3 jetons arrive en entrée, et la phrase française correspondante contient 6 jetons en sortie, alors ils iront au premier groupe et seront remplis jusqu'à la longueur 5 à l'entrée de l'encodeur et la longueur 10 à l'entrée du décodeur. Et s'il y a 8 jetons dans l'offre anglaise et dans les 18 français correspondants, ils ne tomberont pas dans le groupe (10, 15) et seront transférés au groupe (20, 25), c'est-à-dire que l'offre anglaise passera à 20 jetons et la française à 25.

N'oubliez pas que lors de la création de l'entrée du décodeur, nous ajoutons le caractère GO spécial à l'entrée. Cela se produit dans la fonction get_batch() dans seq2seq_model.py , qui retourne également la phrase anglaise. Le retournement de l'entrée a aidé à améliorer les résultats du modèle de traduction neuronale de Sutskever et al., 2014 (pdf). Pour enfin comprendre, imaginez qu'il y a une phrase «Je vais». À l'entrée, divisée en jetons ["I", "go", "."] , Et à la sortie, il y a une phrase «Je vais.», Cassée en jetons ["Je", "vais", "."] . Ils seront ajoutés au groupe (5, 10), avec une représentation du codeur d'entrée [PAD PAD "." "go" "I"] [PAD PAD "." "go" "I"] et entrée décodeur [GO "Je" "vais" "." EOS PAD PAD PAD PAD PAD] [GO "Je" "vais" "." EOS PAD PAD PAD PAD PAD] .

Lancez-le

Pour former le modèle décrit ci-dessus, vous aurez besoin d'un grand corps anglo-français. Pour la formation, nous utiliserons les 10 ^ 9 corps français-anglais du site Web WMT'15 et testerons les nouvelles du même site qu'un échantillon de travail. Les deux jeux de données seront chargés dans train_dir lors de l' train_dir la prochaine commande.

 python translate.py --data_dir [your_data_directory] --train_dir [checkpoints_directory] --en_vocab_size=40000 --fr_vocab_size=40000 

Vous aurez besoin de 18 Go d'espace disque dur et de plusieurs heures pour préparer le bâtiment de formation. Le cas est décompressé, les fichiers de dictionnaire sont créés dans data_dir, puis le cas est tokenisé et converti en identificateurs entiers. Faites attention aux paramètres responsables de la taille du dictionnaire. Dans l'exemple ci-dessus, tous les mots en dehors des 40 000 mots les plus fréquemment utilisés seront convertis en jeton UNK représentant un mot inconnu. Ainsi, lors du changement de la taille du dictionnaire, le binaire réformera le logement par l'identifiant de jeton. Après le début de la formation sur la préparation des données.

Les valeurs spécifiées dans translate sont très élevées par défaut. Les grands modèles qui apprennent depuis longtemps donnent de bons résultats, mais cela peut prendre trop de temps ou trop de mémoire GPU. Vous pouvez spécifier un entraînement de modèle plus petit, comme dans l'exemple ci-dessous.

 python translate.py --data_dir [your_data_directory] --train_dir [checkpoints_directory] --size=256 --num_layers=2 --steps_per_checkpoint=50 

La commande ci-dessus entraînera le modèle avec deux couches (par défaut, il y en a 3), chacune ayant 256 unités (par défaut - 1024), avec un point de contrôle à toutes les 50 étapes (par défaut - 200). Essayez ces options pour voir quel modèle de taille convient à votre GPU.

Pendant l'entraînement, chaque étape du binaire steps_per_checkpoin t donnera des statistiques sur les étapes passées. Avec les paramètres par défaut (3 couches de taille 1024), le premier message est le suivant:

 global step 200 learning rate 0.5000 step-time 1.39 perplexity 1720.62 eval: bucket 0 perplexity 184.97 eval: bucket 1 perplexity 248.81 eval: bucket 2 perplexity 341.64 eval: bucket 3 perplexity 469.04 global step 400 learning rate 0.5000 step-time 1.38 perplexity 379.89 eval: bucket 0 perplexity 151.32 eval: bucket 1 perplexity 190.36 eval: bucket 2 perplexity 227.46 eval: bucket 3 perplexity 238.66 

Notez que chaque étape prend un peu moins de 1,4 seconde, perplexe l'échantillon d'apprentissage et perplexe l'échantillon de travail dans chaque groupe. Après environ 30 mille pas, nous voyons comment les perplexes des phrases courtes (groupes 0 et 1) deviennent sans ambiguïté. Le bâtiment de formation contient environ 22 millions de phrases, une itération (une série de données de formation) prend environ 340 mille pas avec un nombre d'échantillons de formation au nombre de 64. À ce stade, le modèle peut être utilisé pour traduire des phrases anglaises en français en utilisant l'option --decode .

 python translate.py --decode --data_dir [your_data_directory] --train_dir [checkpoints_directory] Reading model parameters from /tmp/translate.ckpt-340000 > Who is the president of the United States? Qui est le président des États-Unis ? 

Et ensuite?

L'exemple ci-dessus montre comment créer votre propre traducteur anglais-français de bout en bout. Exécutez-le et voyez comment fonctionne le modèle. La qualité est acceptable, mais un modèle de traduction idéal ne peut pas être obtenu avec des paramètres par défaut. Voici quelques points à améliorer.

Tout d'abord, nous utilisons la tokenisation primitive, la fonction de base de basic_tokenizer dans data_utils . Un meilleur tokenizer peut être trouvé sur le site Web WMT'15 . Si vous l'utilisez et un grand dictionnaire, vous pouvez obtenir de meilleures traductions.

De plus, les paramètres par défaut du modèle de traduction ne sont pas parfaitement configurés. Vous pouvez essayer de changer la vitesse d'apprentissage, l'atténuation, l'initialisation des poids du modèle. Vous pouvez également remplacer le GradientDescentOptimizer standard dans seq2seq_model.py par quelque chose de plus avancé, comme AdagradOptimizer . Essayez de regarder pour de meilleurs résultats!

Enfin, le modèle présenté ci-dessus peut être utilisé non seulement pour la traduction, mais également pour toute autre tâche de séquence à séquence. Même si vous souhaitez transformer une séquence en arbre, par exemple, générer un arbre d'analyse, ce modèle peut produire des résultats de pointe, comme le montrent Vinyals & Kaiser et al., 2014 (pdf) . Vous pouvez donc créer non seulement un traducteur, mais aussi un analyseur, un chat bot ou tout autre programme que vous souhaitez. Expérimentez!

C'est tout!

Nous attendons vos commentaires et questions ici ou nous vous invitons à demander à leur professeur dans une leçon ouverte .

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


All Articles