Bonne journée à tous!
Et nous avons encore une fois un nouveau flux ouvert pour le cours
Data Scientist révisé: un autre
grand professeur , un programme légèrement raffiné basé sur des mises à jour. Eh bien, comme d'habitude,
des leçons ouvertes intéressantes et des collections de matériel intéressant. Aujourd'hui, nous allons commencer l'analyse des modèles seq2seq de Tensor Flow.
Allons-y.
Comme déjà discuté dans le
tutoriel RNN (nous vous recommandons de vous familiariser avec celui-ci avant de lire cet article), les réseaux de neurones récurrents peuvent être appris à modéliser le langage. Et une question intéressante se pose: est-il possible de former le réseau sur certaines données pour générer une réponse significative? Par exemple, pouvons-nous enseigner à un réseau de neurones à traduire de l'anglais vers le français? Il s'avère que nous le pouvons.
Ce guide vous montrera comment créer et former un tel système de bout en bout. Copiez
le référentiel principal Tensor Flow et
le référentiel modèle TensorFlow depuis GitHub . Ensuite, vous pouvez commencer par lancer le programme de traduction:
cd models/tutorials/rnn/translate python translate.py --data_dir [your_data_directory]

Elle téléchargera les données à traduire de l'anglais vers le français à partir
du site Web WMT'15 , les préparera pour la formation et la formation. Cela nécessitera environ 20 Go sur le disque dur et beaucoup de temps pour télécharger et préparer, vous pouvez donc commencer le processus maintenant et continuer à lire ce tutoriel.
Le manuel accède aux fichiers suivants:
Fichier | Qu'y a-t-il dedans? |
---|
tensorflow / tensorflow / python / ops / seq2seq.py | Bibliothèque pour créer des modèles de séquence à séquence |
models / tutorials / rnn / translate / seq2seq_model.py | Modèles de traduction neuronale séquence à séquence |
models / tutorials / rnn / translate / data_utils.py | Fonctions d'assistance pour la préparation des données de traduction |
modèles / tutoriels / rnn / translate / translate.py | Le binaire qui forme et exécute le modèle de traduction |
Notions de base de séquence à séquenceLe modèle de séquence à séquence de base, tel que présenté par
Cho et al., 2014 (
pdf ), se compose de deux réseaux de neurones récurrents (RNN): un encodeur (encodeur) qui traite les données d'entrée et un décodeur (décodeur) qui génère les données sortie. L'architecture de base est illustrée ci-dessous:

Chaque rectangle dans l'image ci-dessus représente une cellule du RNN, généralement une cellule GRU - un bloc à récurrence contrôlée ou une cellule LSTM - une mémoire à court terme à long terme (lisez le
didacticiel RNN pour en savoir plus à leur sujet). Les encodeurs et décodeurs peuvent avoir des poids communs ou, le plus souvent, utiliser différents ensembles de paramètres. Les cellules multicouches ont été utilisées avec succès dans des modèles de séquence à séquence, par exemple, pour traduire
Sutskever et al., 2014 (
pdf ).
Dans le modèle de base décrit ci-dessus, chaque entrée doit être codée dans un vecteur d'état de taille fixe, car c'est la seule chose qui est transmise au décodeur. Pour donner au décodeur un accès plus direct aux données d'entrée, un mécanisme d'attention a été introduit dans
Bahdanau et al., 2014 (
pdf ). Nous n'entrerons pas dans les détails du mécanisme d'attention (pour cela vous pouvez vous familiariser avec le travail ici); il suffit de dire qu'il permet au décodeur de regarder les données d'entrée à chaque étape de décodage. Un réseau multicouche de séquence à séquence avec des cellules LSTM et le mécanisme d'attention dans le décodeur est le suivant:
Bibliothèque TensorFlow seq2seqComme vous pouvez le voir ci-dessus, il existe différents modèles de séquence à séquence. Tous peuvent utiliser différentes cellules RNN, mais tous acceptent les données d'entrée du codeur et les données d'entrée du décodeur. C'est la base de l'interface de la bibliothèque TensorFlow seq2seq (tensorflow / tensorflow / python / ops / seq2seq.py). Ce modèle de base, RNN, codec, séquence à séquence fonctionne comme suit.
outputs, states = basic_rnn_seq2seq(encoder_inputs, decoder_inputs, cell)
Dans l'appel indiqué ci-dessus,
encoder_inputs
est une liste de tenseurs représentant les données d'entrée de l'encodeur, correspondant aux lettres A, B, C de l'image ci-dessus. De même, les
decoder_inputs
sont des tenseurs représentant les données d'entrée du décodeur. GO, W, X, Y, Z à partir de la première photo.
L'argument de
cell
est une instance de la classe
tf.contrib.rnn.RNNCell
qui détermine quelle cellule sera utilisée dans le modèle. Vous pouvez utiliser des cellules existantes, par exemple,
GRUCell
ou
LSTMCell
, ou vous pouvez écrire les vôtres. De plus,
tf.contrib.rnn
fournit des shells pour créer des cellules multicouches, ajouter des exceptions à l'entrée et à la sortie des cellules, ou d'autres transformations. Consultez le
tutoriel RNN pour des exemples.
L'appel
basic_rnn_seq2seq
renvoie deux arguments: les
outputs
et les
states
. Ils représentent tous les deux une liste de tenseurs de la même longueur que
decoder_inputs
.
outputs
correspondent aux données de sortie du décodeur à chaque pas de temps, dans la première image, il s'agit de W, X, Y, Z, EOS. Les
states
renvoyés représentent l'état interne du décodeur à chaque pas de temps.
Dans de nombreuses applications utilisant le modèle séquence à séquence, la sortie du décodeur à l'instant t est retransmise à l'entrée du décodeur à l'instant t + 1. Pendant les tests, pendant le décodage de séquence, c'est ainsi que l'on en construit un nouveau. D'un autre côté, lors de la formation, il est habituel de transmettre au décodeur les données d'entrée correctes à chaque pas de temps, même si le décodeur s'est précédemment trompé. Les fonctions de
seq2seq.py
prennent en charge les deux modes avec l'argument
feed_previous
. Par exemple, envisagez l'utilisation suivante d'un modèle RNN imbriqué.
outputs, states = embedding_rnn_seq2seq( encoder_inputs, decoder_inputs, cell, num_encoder_symbols, num_decoder_symbols, embedding_size, output_projection=None, feed_previous=False)
Dans le modèle
embedding_rnn_seq2seq
, toutes les données d'entrée (
encoder_inputs
et
decoder_inputs
) sont des tenseurs entiers qui reflètent des valeurs discrètes. Ils seront imbriqués dans une représentation serrée (pour plus de détails sur la pièce jointe, reportez-vous au
Guide des vues vectorielles ), mais pour créer ces pièces jointes, vous devez spécifier le nombre maximal de caractères discrets:
num_encoder_symbols
côté encodeur et
num_decoder_symbols
côté décodeur.
Dans l'appel ci-dessus, nous avons défini
feed_previous
sur False. Cela signifie que le décodeur utilisera les tenseurs
decoder_inputs
sous la forme dans laquelle ils sont fournis. Si nous définissons
feed_previous
sur True, le décodeur n'utilisera que le premier élément
decoder_inputs
. Tous les autres tenseurs de la liste seront ignorés et la valeur précédente de la sortie du décodeur sera utilisée à la place. Il est utilisé pour décoder les traductions dans notre modèle de traduction, mais peut également être utilisé pendant la formation, pour améliorer la stabilité du modèle face à ses erreurs. Approximativement comme dans
Bengio et al., 2015 (
pdf ).
Un autre argument important utilisé ci-dessus est
output_projection
. Sans précision, les conclusions du modèle embarqué seront des tenseurs de la forme du nombre d'échantillons d'apprentissage par
num_decoder_symbols
, car ils représentent les logithmes de chaque symbole généré. Lors de la formation de modèles avec de grands dictionnaires de sortie, par exemple avec de grands
num_decoder_symbols
, le stockage de ces grands tenseurs devient peu pratique. Au lieu de cela, il est préférable de renvoyer des tenseurs plus petits, qui seront ensuite projetés sur le grand tenseur à l'aide de
output_projection
. Cela nous permet d'utiliser nos modèles seq2seq avec des pertes softmax échantillonnées, comme décrit par
Jean et. al., 2014 (
pdf ).
En plus de
basic_rnn_seq2seq
et
embedding_rnn_seq2seq
, il existe plusieurs autres modèles de séquence à séquence dans
seq2seq.py
. Faites attention à eux. Tous ont une interface similaire, nous ne nous attarderons donc pas sur leurs détails. Pour notre modèle de traduction ci-dessous, utilisez
embedding_attention_seq2seq
.
À suivre.