[PYTHON] Langage naturel: ChatBot Part2-Sequence To Sequence Attention

Cible

Ceci est une continuation du chatbot utilisant le Microsoft Cognitive Toolkit (CNTK).

Dans la partie 2, nous formerons des chatbots par CNTK en utilisant les données de conversation préparées dans la partie 1. On suppose que CNTK et NVIDIA GPU CUDA sont installés.

introduction

Natural Language: ChatBot Part1-Twitter API Corpus a préparé un ensemble de données de conversation pour les tweets et les réponses de l'API Twitter.

Dans la partie 2, nous allons créer et former un chatbot en utilisant le modèle de conversion en série [1].

Seq2Seq with Attention Pour la structure globale, je me suis référé à GNMT [2]. En tant que composant du réseau neuronal récursif, l'encodeur et le décodeur sont composés de 5 couches de LSTM [3], et le mécanisme d'attention [4] est introduit.

stsa.png

L'encodeur et le décodeur appliquent la normalisation de couche [5] à la sortie de LSTM.

L'encodeur utilise le RNN bidirectionnel [6] pour concaténer les sorties avant et arrière.

De plus, dans Encoder, après avoir appliqué la normalisation de couche à l'avant et à l'arrière respectivement, puis concaténant, dans Decoder, après l'application de la normalisation de couche, Dropout [[7]](# reference) est inséré pour améliorer les performances de généralisation. Faire.

De plus, l'encodeur et le décodeur utilisent la connexion résiduelle [8] pour améliorer la disparition du gradient qui accompagne l'approfondissement du LSTM. Cependant, la sortie de la couche Embedding n'est pas connectée résiduelle.

Paramètres en formation

La valeur initiale de chaque paramètre a été fixée à une distribution uniforme [2] de [-0,04, 0,04].

Puisqu'il s'agit d'un problème de classification qui prédit le mot suivant, nous avons défini la fonction de perte comme Erreur d'entropie croisée et avons adopté Adam [9] comme algorithme d'optimisation. L'hyperparamètre d'Adam $ \ beta_1 $ est défini sur 0.9 et $ \ beta_2 $ est défini sur la valeur par défaut de CNTK.

Pour le taux d'apprentissage, utilisez le taux d'apprentissage cyclique (CLR) [10], le taux d'apprentissage maximal est de 0,01, le taux d'apprentissage de base est de 1e-4, la taille du pas est de 4 fois le nombre d'époques et la stratégie est exp_range. Installer.

La formation du modèle a effectué 100 Epoch par mini-formation par lots.

la mise en oeuvre

Environnement d'exécution

Matériel

・ Processeur Intel (R) Core (TM) i7-5820K 3,30 GHz ・ GPU NVIDIA Quadro RTX 5000 16 Go

Logiciel

・ Windows 10 Professionnel 1909 ・ CUDA 10.0 ・ CuDNN 7.6 ・ Python 3.6.6 ・ Cntk-gpu 2.7 ・ Cntkx 0.1.33 ・ Pandas 0.25.0

Programme à exécuter

Le programme de formation est disponible sur GitHub.

stsa_training.py


Commentaire

Je compléterai le contenu principal de cette implémentation.

Attention Mechanism Dans le modèle de conversion en série, les informations de série d'entrée sont codées dans un vecteur de longueur fixe par le codeur comme indiqué dans la figure ci-dessous, et l'état caché au dernier moment est défini comme l'état caché initial du décodeur. Cependant, plus la séquence d'entrée est longue, plus il est difficile de compresser les informations.

De plus, les informations à chaque instant doivent être incluses dans l'état caché à chaque instant ($ h ^ E_1, h ^ E_2, ..., h ^ E_ {S-1} $ dans la figure ci-dessous), mais avec le Seq2Seq naïf Le décodeur ne peut recevoir que $ h ^ E_S $ à la dernière fois.

seq2seq.png

Le mécanisme d'attention a été proposé comme remède à ces problèmes et a amélioré les performances du modèle de conversion en série.

Ici, la série d'entrée est $ x_s = (x_1, x_2, ..., x_S) $, la série de sortie est $ y_t = (y_1, y_2, ..., y_T) $, et la fonction de transition de RNN est $ \ Psi ^. Si E $, $ \ Psi ^ D $, l'état caché $ h ^ E_s, h ^ D_t $ à chaque instant du codeur et du décodeur peut être exprimé comme suit.

h^E_s = \Psi^E(x_s, h^E_{s-1}) \\
h^D_t = \Psi^D(y_t, h^D_{t-1})

Ensuite, définissez la fonction $ \ Omega $ pour trouver le poids entre $ h ^ E_s et h ^ D_t $. Cette fois, il est défini comme suit en utilisant les paramètres $ W_ {encoder}, W_ {decoder}, W_ {tanh} $. C'est ce qu'on appelle la mise en garde additive [4], et d'autres mises en garde internes au produit [11] ont été proposées.

\Omega(h^E_s, h^D_t) = W_{tanh} \cdot tanh \left( W_{decoder} \cdot h^D_t + W_{encoder} \cdot h^E_s \right)

Utilisez ensuite la fonction Softmax pour normaliser la somme à 1 pour calculer l'importance de chaque fois pour la série d'entrée.

a_s = \frac{\exp \left( \Omega(h^E_s, h^D_{t-1}) \right)}{\sum \exp \left( \Omega(h^E_s, h^D_{t-1}) \right)}

Ensuite, ce coefficient de pondération $ a_s $ est utilisé pour trouver la somme pondérée $ \ overhead {h} $ de la série d'entrée.

\overline{h} = \sum^S_{s=1} a_s h^E_s

Enfin, concaténez cette moyenne pondérée avec la première couche de Decoder.

h^D_t = \Psi^D \left( \left[ \overline{h}, y_t \right], h^D_{t-1} \right)

En faisant cela, les informations d'état cachées à chaque instant peuvent être efficacement utilisées, et les informations compressées basées sur le temps qui doit être souligné dans la série d'entrée peuvent être transmises au décodeur.

Bidirectional RNN RNN bidirectionnel est le sens avant de la série d'entrée $ x_t = (x_1, x_2, ..., x_T) $ et le sens inverse de la série d'entrée $ x_ {T-t + 1} = (x_T, x_ {T-1}, En utilisant ..., x_1) $ ensemble, vous pouvez considérer les informations de la série d'entrée entière. Cependant, les RNN bidirectionnels doivent avoir toute la séquence d'entrée jusqu'à l'instant $ T $.

La mise en œuvre elle-même est simple, avec deux RNN, un RNN aller et un RNN inverse, qui calculent respectivement les sens aller et retour. Où $ \ overrightarrow {h \ strut} _t et \ overleftarrow {h} _t $ sont les couches cachées avant et arrière au temps $ t $, et $ b et W $ sont le biais et le poids par rapport à l'heure actuelle. $ H $ représente le poids du calque masqué à l'instant précédent.

\overrightarrow{h\strut}_t = \overrightarrow{b\strut} + x_t \overrightarrow{W\strut} + \overrightarrow{h\strut}_{t-1} \overrightarrow{H\strut} \\
\overleftarrow{h}_t = \overleftarrow{b} + x_{T-t+1} \overleftarrow{W} + \overleftarrow{h}_{t-1} \overleftarrow{H}

Il existe plusieurs candidats pour connecter la sortie du RNN bidirectionnel, mais cette fois, les sorties des LSTM aller et retour sont concaténées.

Dans CNTK, vous pouvez l'implémenter en définissant simplement la fonction de récurrence go_backwards sur True.

sequence_to_sequence_attention


h_enc_forward = Recurrence(lstm_forward[i])(h_enc)
h_enc_backward = Recurrence(lstm_backward[i], go_backwards=True))(h_enc)

Residual Connection La connexion résiduelle a été largement utilisée depuis que ResNet [8] a montré qu'il était possible de former des réseaux avec plus de 1 000 couches. ResNet propose une connexion résiduelle qui s'étend sur deux ou plusieurs couches avec un réseau neuronal convolutif, mais la théorie de la connexion résiduelle est simple.

Ici, si l'entrée est $ h $ comme fonction $ f $ de la couche $ l $, la sortie du réseau de la couche $ l $ peut être exprimée comme suit.

f^{(l)}(h)

L'opération d'ajout de la sortie de la couche précédente, c'est-à-dire de l'entrée $ h $, est une connexion résiduelle.

f^{(l)}(h) + h

Alors la différenciation pour $ h $ dans cette équation est

\begin{align}
\frac{\partial (f^{(l)}(h) + h)}{\partial h} &= \frac{\partial f^{(l)}(h)}{\partial h} + \frac{\partial h}{\partial h} \\
&= w^{(l)} + 1
\end{align}

Par conséquent, même si la propagation d'erreur à partir de la couche inférieure est une petite valeur, elle sera proche de 1, il sera donc possible de supprimer la disparition du gradient.

résultat

Training loss and perplexity

La figure ci-dessous est une visualisation de la fonction de perte et des journaux de taux de faux positifs pendant l'entraînement. Le graphique de gauche montre la fonction de perte, le graphique de droite montre la Perplexité, l'axe horizontal montre le nombre d'époques et l'axe vertical montre la valeur et la Perplexité de la fonction de perte, respectivement.

stsa_logging.png

La valeur de la fonction de perte et la Perplexité sont toujours importantes, il semble donc y avoir quelque chose à améliorer.

Conversation avec chatbot

Affiche une conversation avec un chatbot qualifié. La phrase commençant par> est l'entrée, et la phrase commençant par >> est la réponse du chatbot à l'entrée.

>Bonjour
>>Bonjour!
>C'est bravo pour le bon travail
>>Il y a un tsu!
>Suis-moi s'il te plait
>>Suivi!
>Quel est votre nom?
>> w
>Quel est ton passe-temps?
>>Est un passe-temps!
>Il fait beau aujourd'hui, n'est-ce pas
>>Il fait beau!
>Merci pour hier
>>Je suis celui qui devrait te remercier!
>quit

Il semble qu'ils aient une réponse simple, mais ils ont cultivé de l'herbe pour leur nom et n'ont pas appris le concept de passe-temps.

Visualisation de l'attention

Attention améliore non seulement les performances du Seq2Seq naïf, mais vous permet également de visualiser la relation entre les chaînes de mots d'entrée et prédites à l'aide des cartes Attention. La figure ci-dessous montre un exemple de carte Attention, l'axe horizontal représente la séquence de mots d'entrée, l'axe vertical représente la séquence de mots prédite et la carte de couleurs est affichée comme chaude.

attention.png

Dans cet exemple, le mot d'entrée «beau temps» semble être plus important que les autres mots.

référence

CNTK 204: Sequence to Sequence Networks with Text Data

Natural Language : ChatBot Part1 - Twitter API Corpus

  1. Ilya Sutskever, Oriol Vinyals, and Quoc V. Le. "Sequence to Sequence Learning with Neural Networks", Advances in neural information processing systems. 2014, pp 3104-3112.
  2. Yougnhui Wu, Mike Schuster, Zhifen Chen, Quoc V. Le, Mohammad Norouzi, et. al. "Google's Neural Machine Translation System: Bridging the Gap between Human and Machine Translation", arXiv preprint arXiv:1609.08144, 2016.
  3. Sepp Hochreiter, and Jürgen Schmidhuber. "Long Short-Term Memory", Neural Computation. 1997, pp 1735-1780.
  4. Dzmitry Bahdanau, KyungHyun Cho, and Yoshua Bengio. "Neural Machine Translation by Jointly Learning to Align and Translate", arXiv preprint arXiv:1409.0473, 2014.
  5. Jimmy Lei Ba, Jamie Ryan Kiros, and Geoffrey E. Hinton. "Layer Normalization", arXiv preprint arXiv:1607.06450 (2016).
  6. Mike Schuster and Luldip K. Paliwal. "Bidirectional Recurrent Neural Networks", IEEE transactions on Signal Processing, 45(11), 1997, pp 2673-2681.
  7. Alex Krizhevsky, Ilya Sutskever, and Geoffrey E.Hinton. "ImageNet Classification with Deep Convolutional Neural Networks", Advances in neural information processing systems. 2012, pp 1097-1105.
  8. Kaiming He, Xiangyu Zhang, Shaoqing Ren, and Jian Sun. "Deep Residual Learning for Image Recognition", the IEEE conference on computer vision and pattern recognition. 2016. pp 770-778.
  9. Diederik P. Kingma and Jimmy Lei Ba. "Adam: A method for stochastic optimization", arXiv preprint arXiv:1412.6980 (2014).
  10. Leslie N. Smith. "Cyclical Learning Rates for Training Neural Networks", 2017 IEEE Winter Conference on Applications of Computer Vision. 2017, pp 464-472.
  11. Minh-Thang Luong, Hieu Pham, and Christopher D. Manning. "Effective Approaches to Attention-based Neural Machine Translation", arXiv preprint arXiv:1508.04025, 2015.

Recommended Posts

Langage naturel: ChatBot Part2-Sequence To Sequence Attention
Se préparer à démarrer le traitement du langage naturel
Langage naturel: ChatBot Part1-Twitter API Corpus
Insoutenable manque d'attention dans le traitement du langage naturel
Python: traitement du langage naturel
Introduction au langage Python
RNN_LSTM2 Traitement du langage naturel
[Python] Essayez de classer les boutiques de ramen par traitement du langage naturel