[PYTHON] TensorFlow Tutorial-Sequenztransformationsmodell (Übersetzung)

TensorFlow Tutorial (Sequenz-zu-Sequenz-Modelle) https://www.tensorflow.org/versions/master/tutorials/seq2seq/index.html#sequence-to-sequence-models Es ist eine Übersetzung von. Wir freuen uns darauf, auf Übersetzungsfehler hinzuweisen.


Lesen Sie das wiederkehrende neuronale Netzwerk wie in RNN Tutorial beschrieben (wenn Sie es nicht gelesen haben, lesen Sie es, bevor Sie fortfahren. Sie können lernen, die Sprache zu modellieren. Dies wirft eine interessante Frage auf: Ist es möglich, eine aussagekräftige Antwort auf Wörter zu generieren, die durch eine Eingabe generiert wurden? Können Sie beispielsweise ein neuronales Netzwerk trainieren, um vom Englischen ins Französische zu übersetzen? Die Antwort war ja.

Dieses Tutorial zeigt Ihnen, wie Sie ein solches System von Ende zu Ende erstellen und trainieren. Angenommen, Sie werden vom Pip-Paket installiert, klonen das Tensorflow-Git-Repository und befinden sich im Stammverzeichnis des Git-Baums.

Führen Sie zunächst das Übersetzungsprogramm aus:

cd tensorflow/models/rnn/translate
python translate.py --data_dir [your_data_directory]

Dieses Programm lädt englisch-französische Übersetzungsdaten von der WMT'15-Website herunter, bereitet sich auf Schulungen vor und trainiert. .. Es benötigt ungefähr 20 GB Speicherplatz. Ich werde eine Weile herunterladen und vorbereiten (siehe unten für Details (https://www.tensorflow.org/versions/master/tutorials/seq2seq/index.html#run_it)). Beginnen Sie also und lesen Sie dieses Tutorial. Es ist eine gute Idee, es am Laufen zu halten, während Sie gerade dabei sind.

In diesem Tutorial werden wir auf die folgenden Dateien in models / rnn verweisen.

Datei Inhalt
seq2seq.py Bibliothek zum Erstellen von Sequenztransformationsmodellen
translate/seq2seq_model.py Transformationsmodell für neuronale Translationssequenzen
translate/data_utils.py Hilfsfunktion zur Vorbereitung von Übersetzungsdaten
translate/translate.py Eine Binärdatei, die ein Übersetzungsmodell trainiert und ausführt

Grundlagen der Sequenzkonvertierung

Das grundlegende Sequenztransformationsmodell besteht aus zwei wiederkehrenden neuronalen Netzen (RNNs), wie in Cho et al., 2014 eingeführt. : Ein Encoder, der den Eingang verarbeitet, und ein Decoder, der den Ausgang erzeugt. Die grundlegende Architektur ist unten dargestellt.

図

Jedes Feld in der obigen Abbildung ist eine RNN-Zelle, am häufigsten eine GRU-Zelle oder eine LSTM-Zelle (eine Beschreibung finden Sie in den RNN-Tutorials (https://www.tensorflow.org/versions/master/tutorials). (siehe /recurrent/index.html)) wird ausgedrückt. Codierer und Decodierer können auch Gewichte gemeinsam nutzen und im Allgemeinen separate Parametersätze verwenden. Mehrschichtzellen werden auch erfolgreich in Sequenztransformationsmodellen verwendet, beispielsweise [Sutskever et al., 2014] zur Übersetzung (http://arxiv.org/abs/1409.3215).

In dem oben gezeigten Basismodell müssen alle Eingaben in einen Zustandsvektor fester Größe codiert werden, als das einzige, was an den Decoder übergeben wird. Bahdanu et al., 2014 führt einen Aufmerksamkeitsmechanismus ein, mit dem der Decoder direkter auf den Eingang zugreifen kann. Ich werde nicht auf die Details des interessierenden Mechanismus eingehen (siehe Papier). Es ist nur zu erwähnen, dass der Decoder bei jedem Decodierungsschritt die Eingabe einschleichen kann. Ein mehrschichtiges Sequenzkonvertierungsnetzwerk mit dem LSTM-Zellen- und Decoderfokusmechanismus sieht folgendermaßen aus:

図

TensorFlow seq2seq Bibliothek

Wie Sie oben sehen können, gibt es eine Vielzahl von Sequenztransformationsmodellen. Jedes dieser Modelle verwendet eine andere RNN-Zelle, aber alle akzeptieren Encoder- und Decoder-Eingänge. Dadurch wird eine Schnittstelle in der seq2seq-Bibliothek von TensorFlow (models / rnn / seq2seq.py) angezeigt. Das grundlegende RNN-Encoder-Decoder-Sequenz-Konvertierungsmodell funktioniert wie folgt.

outputs, states = basic_rnn_seq2seq(encoder_inputs, decoder_inputs, cell)

Im obigen Aufruf entspricht encoder_inputs der Liste der Tensoren, die die Eingaben in den Encoder darstellen, dh den Buchstaben A, B und C in der ersten Abbildung oben. In ähnlicher Weise sind decoder_inputs Tensoren, die die Eingaben in den Decoder GO, W, X, Y, Z in der ersten Figur darstellen.

Das Zellenargument ist eine Instanz der Klasse models.rnn.rnn_cell.RNNCell, die die im Modell verwendeten Zellen definiert. Sie können vorhandene Zellen wie GRUCell und LSTMCell verwenden oder eigene schreiben. Rnn_cell bietet auch einen Wrapper zum Erstellen von mehrschichtigen Zellen zum Hinzufügen von Aussetzern zu Zelleingaben und -ausgaben sowie für andere Transformationen. Ein Beispiel finden Sie im RNN-Lernprogramm (https://www.tensorflow.org/versions/master/tutorials/recurrent/index.html).

Der Aufruf von basic_rnn_seq2seq gibt zwei Argumente zurück: output und state. Beides sind Listen von Tensoren, die dieselbe Länge wie decoder_inputs haben. Es ist nicht überraschend, dass die Ausgabe der Ausgabe des Decoders zu jedem Zeitschritt W, X, Y, Z, EOS in der ersten Abbildung oben entspricht. Der zurückgegebene Zustand repräsentiert den internen Zustand des Decoders bei jedem Zeitschritt.

In vielen Fällen gibt das Sequenzkonvertierungsmodell den Ausgang des Decoders zum Zeitpunkt t zurück und wird zum Eingang des Decoders zum Zeitpunkt t + 1. So wird die Sequenz aufgebaut, wenn die Sequenz während des Tests dekodiert wird. Andererseits geben Sie während des Trainings in der Regel zu jedem Zeitpunkt die richtige Antwort in den Decoder ein, auch wenn der Decoder im vorherigen Schritt einen Fehler gemacht hat. Die Funktion seq2seq.py verwendet das Argument feed_previous, um beide Modi zu unterstützen. Lassen Sie uns als Beispiel die folgende Verwendung des eingebetteten RNN-Modells analysieren.

outputs, states = embedding_rnn_seq2seq(
    encoder_inputs, decoder_inputs, cell,
    num_encoder_symbols, num_decoder_symbols,
    output_projection=None, feed_previous=False)

Im Embedding_rnn_seq2seq-Modell sind alle Eingaben (sowohl Encoder_Eingänge als auch Decoder_Eingänge) ganzzahlige Tensoren, die diskrete Werte darstellen. Diese sind in dichte Darstellungen eingebettet (weitere Informationen zum Einbetten finden Sie im Vector Expression Tutorial (https://www.tensorflow.org/versions/master/tutorials/word2vec/index.html). Bitte), um diese Einbettungen zu erstellen, müssen Sie die maximale Anzahl diskreter Symbole angeben, die angezeigt werden: num_encoder_symbols auf der Encoderseite und num_decoder_symbols auf der Decoderseite.

Im obigen Aufruf setzen wir feed_previous auf False. Dies bedeutet, dass der Decoder den bereitgestellten Tensor decoder_inputs verwendet. Wenn feed_previous auf True gesetzt ist, verwendet der Decoder nur das erste Element von decoder_inputs. Alle anderen Tensoren in dieser Liste werden ignoriert und stattdessen wird die vorherige Ausgabe des Encoders verwendet. Dies wird für die Entschlüsselungskonvertierung in unserem Übersetzungsmodell verwendet. Es kann auch während des Trainings verwendet werden, z. B. Bengio et al., 2015, um das Modell gegenüber eigenen Fehlern robuster zu machen. Ich kann es schaffen

Ein weiteres wichtiges Argument, das oben verwendet wurde, ist output_projection. Wenn dies nicht angegeben ist, ist die Ausgabe des eingebetteten Modells ein Tensor in Form der Stapelgröße x num_decoder_symbols, der die Protokollierung jedes generierten Symbols darstellt. Wenn Sie Ihr Modell mit einem großen Ausgabevokabular trainieren, d. H. Mit großen num_decoder_symbolen, ist es nicht praktisch, diese großen Tensoren zu speichern. Stattdessen wird empfohlen, einen kleinen Ausgangstensor zurückzugeben. Sie werden später mit output_projection auf einen großen Ausgangstensor projiziert. Dies ermöglicht es uns, unser seq2seq-Modell mit Stichproben-Softmax-Verlusten zu verwenden, wie in Jean et al., 2015 beschrieben. Ich kann.

Zusätzlich zu basic_rnn_seq2seq und embedded_rnn_seq2seq gibt es in seq2seq.py mehrere Sequenzkonvertierungsmodelle. Schauen Sie sich diese an. Sie haben alle ähnliche Schnittstellen und werden nicht im Detail besprochen. Das folgende Übersetzungsmodell verwendet embeddedding_attention_seq2seq.

Neuronales Übersetzungsmodell

Das Herzstück des Sequenztransformationsmodells besteht aus den Funktionen in models / rnn / seq2seq.py, aber es gibt einige erwähnenswerte Tricks, die im Übersetzungsmodell in models / rnn / translate / seq2seq_model.py verwendet werden. Es gibt.

Sampling von Softmax und Ausgangsprojektion

Verwenden Sie Sampling Softmax, um aus den oben genannten Gründen ein großes Ausgabevokabular zu verarbeiten. Es wird aus der Ausgabeprojektion dekodiert, sodass Sie den Überblick behalten müssen. Sowohl der Abtast-Softmax-Verlust als auch die Ausgabevorhersage werden mit dem folgenden Code in seq2seq_model.py erstellt.

  if num_samples > 0 and num_samples < self.target_vocab_size:
    w = tf.get_variable("proj_w", [size, self.target_vocab_size])
    w_t = tf.transpose(w)
    b = tf.get_variable("proj_b", [self.target_vocab_size])
    output_projection = (w, b)

    def sampled_loss(inputs, labels):
      labels = tf.reshape(labels, [-1, 1])
      return tf.nn.sampled_softmax_loss(w_t, b, inputs, labels, num_samples,
                                        self.target_vocab_size)

Beachten Sie zunächst, dass wir Sampling-Softmax nur erstellen, wenn die Anzahl der Samples (standardmäßig 512) kleiner als die Zielvokabulargröße ist. Wenn Ihr Wortschatz weniger als 512 beträgt, verwenden Sie am besten nur den Standard-Softmax-Verlust.

Erstellen Sie dann die Ausgabeprojektion, wie Sie im Code sehen können. Dies ist ein Paar aus Gewichtsmatrix und Bias-Vektor. Bei Verwendung gibt die RNN-Zelle einen Vektor von Formen in Stapelgröße x Größe anstelle von Stapelgröße x target_vocab_size zurück. Sie müssen die Gewichtsmatrix multiplizieren und vorspannen, um das Protokoll abzurufen, wie in den Zeilen 124-126 von seq2seq_model.py beschrieben.

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

Schaufeln und Polstern

Zusätzlich zu Sampling Softmax verwendet unser Übersetzungsmodell Bucketing, mit dem Sätze unterschiedlicher Länge effizient verarbeitet werden können. Lassen Sie uns zuerst das Problem klären. Bei der Übersetzung von Englisch ins Französische werden L1-Sätze mit variabler Länge und L2-Sätze mit variabler Länge eingegeben. Da der englische Satz als encoder_inputs übergeben wird und als decoder_inputs (beginnend mit dem GO-Symbol) zum französischen Satz wird, erstellen Sie im Prinzip ein seq2seq-Modell für alle Paare (L1, L2 + 1) der englischen und französischen Satzlängen. wird gebraucht. Dies ist eine riesige Grafik, die aus vielen sehr ähnlichen Untergraphen besteht. Andererseits können alle Anweisungen auch mit einem speziellen PAD-Symbol aufgefüllt werden. In diesem Fall benötigen Sie das Modell seq2seq nur für die einzige gepolsterte Länge. Kurze Anweisungen machen dieses Modell jedoch ineffizient, da eine große Anzahl unnötiger PAD-Symbole codiert und decodiert werden muss.

Verwenden Sie als Kompromiss zwischen dem Erstellen eines Diagramms für alle Längenpaare und dem Auffüllen auf eine einzelne Länge mehrere Buckets und verlängern Sie jeden Satz. Machen Sie die Polsterung für. translate.py verwendet den folgenden Standard-Bucket:

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

Dies wird in den ersten Bucket gestellt, wenn der Eingang ein englischer 3-Token-Satz und der entsprechende Ausgang ein französischer 6-Token-Satz ist, der Encoder-Eingang 5 lang und der Decoder-Eingang 10 lang ist. Es bedeutet gepolstert zu sein. Wenn Sie einen englischen Satz mit 8 Token haben und der entsprechende französische Satz 18 Token ist, wird der Eimer (20, 25) verwendet, da er nicht in den Eimer (10, 15) passt, dh der englische Satz ist 20 und französisch. Der Satz wird auf 25 aufgefüllt.

Denken Sie daran, dass wir beim Erstellen des Decodereingangs den Eingabedaten ein spezielles GO-Symbol hinzufügen. Dies geschieht mit der Funktion get_batch () in seq2seq_model.py. Diese Funktion invertiert auch den eingegebenen englischen Text. Die Umkehrung der Eingabe wurde in Sutskever et al., 2014 gezeigt, um die Ergebnisse des neuronalen Übersetzungsmodells zu verbessern. Um alles zusammenzusetzen, gibt es den Satz "Ich gehe". Als Eingabe, gekennzeichnet als ["Ich", "Gehen", "."] Und den Satz "Je vais". Als Ausgabe, [" Nehmen wir an, es wird als Je "," vais ",". "] Tokenisiert. In diesem Fall der durch [PAD PAD "." "Go" "I"] dargestellte Encodereingang und der durch [GO "Je" "vais" "dargestellte Decodereingang." EOS PAD PAD PAD PAD PAD](5, 10) Kann in einen Eimer gegeben werden.

Lass uns rennen

Ein großer englisch-französischer Korpus ist erforderlich, um das obige Modell zu trainieren. Verwenden Sie auf der WMT'15-Website einen 10 ^ 9 französisch-englischen Korpus für Schulungen und als Entwicklungsset von derselben Website Verwenden Sie den News-Test 2013. Wenn Sie den Befehl ausführen, werden diese Datensätze in data_dir heruntergeladen, das Training beginnt und Checkpoints werden in train_dir gespeichert.

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

Die Vorbereitung des Trainingskorpus dauert etwa 18 GB Speicherplatz und mehrere Stunden. Die Vorbereitung entpackt den Datensatz, erstellt eine lexikalische Datei in data_dir, markiert den Korpus und konvertiert ihn in eine Ganzzahl-ID. Achten Sie auf die Parameter, die die Vokabulargröße bestimmen. Im obigen Beispiel werden alle bis auf die häufigsten 40.000 Wörter in UNK-Token konvertiert, die unbekannte Wörter darstellen. Wenn Sie die Vokabulargröße ändern, konvertiert die Binärdatei den Korpus erneut in Token und IDs.

Nachdem die Daten vorbereitet wurden, beginnt das Training. Der Standardparameter für die Übersetzung ist so eingestellt, dass ein großer Wert verwendet wird. Größere Modelle, die über einen langen Zeitraum trainiert wurden, liefern gute Ergebnisse. Es kann jedoch zu lange dauern oder der GPU kann der Arbeitsspeicher ausgehen, sodass Sie wie im folgenden Beispiel anfordern können, ein kleineres Modell zu trainieren.

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

Der obige Befehl trainiert ein Modell mit 2 Ebenen (Standard 3), 256 Einheiten für jede Ebene (Standard 1024) und speichert alle 50 Schritte Prüfpunkte (Standard 200). Sie können zulassen, dass das Modell in den Speicher der GPU passt. Sie können diese Parameter ändern, damit das Modell in den Speicher der GPU passt.

Während des Trainings gibt die Binärdatei bei jedem Schritt step_per_checkpoint Statistiken des letzten Schritts aus. Mit den Standardparametern (drei Ebenen, Größe 1024) sieht die erste Nachricht folgendermaßen aus:

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

Sie können sehen, dass jeder Schritt weniger als 1,4 Sekunden dauert und die Ratlosigkeit des Trainingssatzes und die Ratlosigkeit des Entwicklungssatzes für jeden Bucket. Stellen Sie nach ca. 30.000 Schritten sicher, dass die Verwirrung der kurzen Sätze (Buckets 0 und 1) einstellig ist. Da der Trainingskorpus ungefähr 22 Millionen Sätze enthält, beträgt eine Epoche (der Zeitraum eines Zyklus von Trainingsdaten) 64 Chargengrößen und ungefähr 340.000 Schritte. An dieser Stelle können Sie das Modell verwenden, um englische Sätze mit der Option --decode ins Französische zu übersetzen.

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 ?

Nächster?

Das obige Beispiel zeigt, wie Sie Ihren eigenen Englisch-Französisch-Übersetzer von Ende zu Ende erstellen. Führen Sie es aus und sehen Sie, wie das Modell funktioniert. Es ist von einigermaßen guter Qualität, aber die Standardparameter liefern nicht das beste Übersetzungsmodell. Es gibt einige Dinge, die hier verbessert werden können.

Zunächst verwendeten wir in data_utils die sehr primitive Tokenizer-Funktion basic_tokenizer. Einen besseren Tokenizer finden Sie auf der WMT'15-Website (http://www.statmt.org/wmt15/translation-task.html). Die Verwendung dieses Tokenizers und eines größeren Wortschatzes sollte die Übersetzung verbessern.

Außerdem werden die Standardparameter des Übersetzungsmodells nicht angepasst. Sie können die Trainingsrate und den Zerfall ändern oder versuchen, die Modellgewichte auf andere Weise zu initialisieren. Sie können den Standard-GradientDescentOptimizer in seq2seq_model.py auch in einen erweiterten Code ändern, z. B. AdagradOptimizer. Probieren Sie diese Dinge aus und sehen Sie, wie sich die Ergebnisse verbessern!

Schließlich kann das obige Modell für jede Sequenzkonvertierungsaufgabe verwendet werden, nicht nur für die Übersetzung. Wenn Sie beispielsweise eine Sequenz in einen Baum konvertieren möchten, um einen Syntaxanalysebaum zu generieren, wie in Vinyals & Kaiser et al., 2015 gezeigt. Das Modell liefert innovative Ergebnisse. Sie können Ihren eigenen Übersetzer sowie Parser, Chatbots oder jedes andere Programm erstellen, an das Sie denken können. Experiment!

Recommended Posts

TensorFlow Tutorial-Sequenztransformationsmodell (Übersetzung)
TensorFlow Tutorial - TensorFlow Mechanics 101 (Übersetzung)
TensorFlow Tutorial-Bilderkennung (Übersetzung)
Sprachvorhersagemodell von TensorFlow
TensorFlow Tutorial-Partielle Differentialgleichungen (Übersetzung)
[FSL] Affine Umwandlung (parallele Bewegung + lineare Umwandlung)
TensorFlow Tutorial-Convolution Neuronales Netz (Übersetzung)
TensorFlow MNIST Für ML Anfänger Übersetzung
Passen Sie Modell / Ebene / Metrik mit TensorFlow an
So konvertieren Sie das Tensorflow-Modell in Lite
TensorFlow Tutorial-Vektordarstellung von Wörtern (Übersetzung)
[Übersetzung] scikit-learn 0.18 Benutzerhandbuch 3.4. Modellpersistenz
TensorFlow Deep MNIST für Expertenübersetzung