[PYTHON] Natürliche Sprache: ChatBot Part2-Sequenz zu Sequenz Aufmerksamkeit

Ziel

Dies ist eine Fortsetzung des Chatbots mit dem Microsoft Cognitive Toolkit (CNTK).

In Teil 2 werden wir Chatbots von CNTK anhand der in Teil 1 vorbereiteten Konversationsdaten trainieren. Es wird davon ausgegangen, dass CNTK und NVIDIA GPU CUDA installiert sind.

Einführung

Natürliche Sprache: ChatBot Part1-Twitter API Corpus hat einen Konversationsdatensatz für Tweets und Antworten von der Twitter-API vorbereitet.

In Teil 2 erstellen und trainieren wir einen Chatbot mit dem Serienkonvertierungsmodell [1].

Seq2Seq with Attention Für die Gesamtstruktur habe ich mich auf GNMT [2] bezogen. Als Komponente des rekursiven neuronalen Netzwerks bestehen sowohl Encoder als auch Decoder aus 5 Schichten LSTM [3], und der Aufmerksamkeitsmechanismus [4] wird eingeführt.

stsa.png

Sowohl Encoder als auch Decoder wenden die Layernormalisierung [5] auf den Ausgang von LSTM an.

Der Encoder verwendet Bidirectional RNN [6], um Vorwärts- und Rückwärtsausgänge zu verketten.

Außerdem wird in Encoder nach dem Anwenden der Ebenennormalisierung auf Vorwärts bzw. Rückwärts und dem anschließenden Verketten im Decoder nach dem Anwenden der Ebenennormalisierung Dropout [[7]](# Referenz) eingefügt, um die Generalisierungsleistung zu verbessern. Machen.

Darüber hinaus verwenden sowohl Encoder als auch Decoder Residual Connection [8], um das mit der Vertiefung von LSTM einhergehende Verschwinden des Gradienten zu verbessern. Die Ausgabe von der Einbettungsschicht ist jedoch nicht restverbunden.

Einstellungen im Training

Der Anfangswert jedes Parameters wurde auf eine gleichmäßige Verteilung [2] von [-0,04, 0,04] eingestellt.

Da es sich um ein Klassifizierungsproblem handelt, das das nächste Wort vorhersagt, haben wir die Verlustfunktion als Cross Entropy Error festgelegt und Adam [9] als Optimierungsalgorithmus übernommen. Adams Hyperparameter $ \ beta_1 $ werden auf 0,9 und $ \ beta_2 $ auf die CNTK-Standardwerte gesetzt.

Verwenden Sie für die Lernrate die zyklische Lernrate (CLR) [10], die maximale Lernrate beträgt 0,01, die Basislernrate beträgt 1e-4, die Schrittgröße beträgt das 4-fache der Anzahl der Epochen und die Strategie lautet exp_range. Installieren.

Das Modelltraining führte 100 Epochen durch Mini-Batch-Training durch.

Implementierung

Ausführungsumgebung

Hardware-

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

Software

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

Programm zum Ausführen

Das Schulungsprogramm ist auf [GitHub] verfügbar (https://github.com/sho-watari/NaturalLanguage/tree/master/STSA).

stsa_training.py


Kommentar

Ich werde den Hauptinhalt dieser Implementierung ergänzen.

Attention Mechanism In dem Serienkonvertierungsmodell werden die eingegebenen Serieninformationen von Encoder in einen Vektor fester Länge codiert, wie in der folgenden Abbildung gezeigt, und der verborgene Zustand zum letzten Mal wird als der anfängliche verborgene Zustand des Decoders festgelegt. Je länger die Eingabesequenz ist, desto schwieriger ist es jedoch, die Informationen zu komprimieren.

Außerdem sollten die Informationen zu jedem Zeitpunkt im verborgenen Zustand enthalten sein ($ h ^ E_1, h ^ E_2, ..., h ^ E_ {S-1} $ in der folgenden Abbildung), jedoch mit dem naiven Seq2Seq Der Decoder kann nur $ h ^ E_S $ zum letzten Mal empfangen.

seq2seq.png

Der Aufmerksamkeitsmechanismus wurde als Lösung für diese Probleme vorgeschlagen und verbesserte die Leistung des Serienkonvertierungsmodells.

Hier ist die Eingabeserie $ x_s = (x_1, x_2, ..., x_S) $, die Ausgabeserie ist $ y_t = (y_1, y_2, ..., y_T) $ und die Übergangsfunktion von RNN ist $ \ Psi ^. Wenn E $, $ \ Psi ^ D $, kann der verborgene Zustand $ h ^ E_s, h ^ D_t $ zu jedem Zeitpunkt von Encoder und Decoder wie folgt ausgedrückt werden.

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

Definieren Sie als nächstes die Funktion $ \ Omega $, um das Gewicht zwischen $ h ^ E_s und h ^ D_t $ zu ermitteln. Dieses Mal wird es unter Verwendung der Parameter $ W_ {Encoder}, W_ {Decoder}, W_ {tanh} $ wie folgt definiert. Dies wird als additive Vorsicht [4] bezeichnet, und andere interne Produktwarnungen [11] wurden vorgeschlagen.

\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)

Verwenden Sie dann die Softmax-Funktion, um die Summe auf 1 zu normalisieren und die Wichtigkeit jedes Mal für die Eingabeserie zu berechnen.

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)}

Dieser Gewichtungskoeffizient $ a_s $ wird dann verwendet, um die gewichtete Summe $ \ overhead {h} $ der Eingabeserie zu ermitteln.

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

Verketten Sie schließlich diesen gewichteten Durchschnitt mit der ersten Schicht des Decoders.

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

Auf diese Weise können die verborgenen Zustandsinformationen zu jedem Zeitpunkt effektiv genutzt werden, und die komprimierten Informationen basierend auf der Zeit, die in der Eingabeserie hervorgehoben werden sollte, können an den Decoder übergeben werden.

Bidirectional RNN Bidirektionales RNN ist die Vorwärtsrichtung der Eingabeserie $ x_t = (x_1, x_2, ..., x_T) $ und die Rückwärtsrichtung der Eingabeserie $ x_ {T-t + 1} = (x_T, x_ {T-1}, Wenn Sie ..., x_1) $ zusammen verwenden, können Sie die Informationen der gesamten Eingabeserie berücksichtigen. Bidirektionale RNNs müssen jedoch die gesamte Eingabesequenz bis zum Zeitpunkt $ T $ haben.

Die Implementierung selbst ist einfach, mit zwei RNNs, einem Vorwärts-RNN und einem Rückwärts-RNN, die die Vorwärts- bzw. Rückwärtsrichtung berechnen. Wobei $ \ overrightarrow {h \ strut} _t und \ overleftarrow {h} _t $ die vorwärts und rückwärts verborgenen Schichten zum Zeitpunkt $ t $ sind und $ b und W $ die Vorspannung und das Gewicht in Bezug auf die aktuelle Zeit sind. $ H $ repräsentiert das Gewicht für die verborgene Ebene zum vorherigen Zeitpunkt.

\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}

Es gibt mehrere Kandidaten zum Verbinden der Ausgabe des bidirektionalen RNN, aber diesmal werden die Ausgaben der Vorwärts- und Rückwärts-LSTMs verkettet.

In CNTK können Sie es implementieren, indem Sie einfach die Wiederholungsfunktion go_backwards auf True setzen.

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 Residual Connection ist weit verbreitet, seit ResNet [8] gezeigt hat, dass es möglich ist, Netzwerke mit mehr als 1.000 Schichten zu trainieren. ResNet schlägt eine Restverbindung vor, die zwei oder mehr Schichten mit einem Faltungsnetzwerk überspannt, aber die Theorie der Restverbindung ist einfach.

Wenn hier die Eingabe $ h $ als Funktion $ f $ der Schicht $ l $ ist, kann die Ausgabe des Netzwerks der Schicht $ l $ wie folgt ausgedrückt werden.

f^{(l)}(h)

Die Operation des Hinzufügens der Ausgabe der vorherigen Ebene, dh der Eingabe $ h $, zu dieser ist eine Restverbindung.

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

Dann ist die Differenzierung für $ h $ in dieser Gleichung

\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}

Selbst wenn die Fehlerausbreitung von der unteren Schicht ein kleiner Wert ist, liegt sie nahe bei 1, so dass das Verschwinden des Gradienten unterdrückt werden kann.

Ergebnis

Training loss and perplexity

Die folgende Abbildung zeigt die Verlustfunktion und die Protokolle mit falsch positiven Raten während des Trainings. Das Diagramm links zeigt die Verlustfunktion, das Diagramm rechts zeigt die Ratlosigkeit, die horizontale Achse zeigt die Anzahl der Epochen und die vertikale Achse zeigt den Wert bzw. die Ratlosigkeit der Verlustfunktion.

stsa_logging.png

Sowohl der Wert der Verlustfunktion als auch die Ratlosigkeit sind immer noch groß, daher scheint es etwas zu geben, das verbessert werden muss.

Gespräch mit Chatbot

Zeigt ein Gespräch mit einem geschulten Chatbot. Der mit> beginnende Satz ist die Eingabe, und der mit >> beginnende Satz ist die Antwort des Chatbots auf die Eingabe.

>Hallo
>>Hallo!
>Ist Prost auf gute Arbeit
>>Es gibt ein Tsu!
>Bitte folgen Sie mir
>>Gefolgt!
>Wie heißen Sie?
>> w
>Was ist dein Hobby?
>>Ist ein Hobby!
>Das Wetter ist heute gut, nicht wahr?
>>Es ist schönes Wetter!
>Danke für gestern
>>Ich bin derjenige, der dir danken sollte!
>quit

Es scheint, dass sie eine einfache Antwort haben, aber sie haben Gras für ihre Namen angebaut und das Konzept der Hobbys nicht gelernt.

Aufmerksamkeitsvisualisierung

Attention verbessert nicht nur die Leistung des naiven Seq2Seq, sondern ermöglicht es Ihnen auch, die Beziehung zwischen Eingabe und vorhergesagten Wortfolgen mithilfe von Attention Maps zu visualisieren. Die folgende Abbildung zeigt ein Beispiel für eine Aufmerksamkeitskarte, die horizontale Achse repräsentiert die eingegebene Wortsequenz, die vertikale Achse repräsentiert die vorhergesagte Wortsequenz und die Farbkarte wird als heiß angezeigt.

attention.png

In diesem Beispiel scheint das Eingabewort "gutes Wetter" wichtiger zu sein als die anderen Wörter.

Referenz

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

Natürliche Sprache: ChatBot Part2-Sequenz zu Sequenz Aufmerksamkeit
Vorbereitung zum Starten der Verarbeitung natürlicher Sprache
Natürliche Sprache: ChatBot Part1-Twitter API Corpus
Unerträgliche Aufmerksamkeitsmangel bei der Verarbeitung natürlicher Sprache
Python: Verarbeitung natürlicher Sprache
Einführung in die Python-Sprache
RNN_LSTM2 Verarbeitung natürlicher Sprache
[Python] Versuchen Sie, Ramen-Shops durch Verarbeitung natürlicher Sprache zu klassifizieren