[PYTHON] TensorFlow Tutorial-Vektordarstellung von Wörtern (Übersetzung)

TensorFlow Tutorial (Vektordarstellungen von Wörtern) https://www.tensorflow.org/versions/master/tutorials/word2vec/index.html Es ist eine Übersetzung von. Wir freuen uns darauf, auf Übersetzungsfehler hinzuweisen.


In diesem Tutorial werden wir uns das word2vec-Modell von Mikolov et al. ansehen. Ich werde fortsetzen. Dieses Modell wird verwendet, um eine Vektordarstellung von Wörtern zu lernen, die als "Worteinbettung" bezeichnet werden.

Markieren

Dieses Tutorial soll den interessanten und inhaltlichen Teil der Erstellung eines word2vec-Modells in TensorFlow hervorheben.

Wir werden den Code später im Tutorial behandeln, aber wenn Sie lieber direkt loslegen möchten, tensorflow / examples / tutorials / word2vec / word2vec_basic.py Siehe die minimale Implementierung von /tensorflow/examples/tutorials/word2vec/word2vec_basic.py). Dieses grundlegende Beispiel enthält den Code, der zum Herunterladen einiger Daten, zum Trainieren dieser Daten und zum Visualisieren der Ergebnisse erforderlich ist. Sobald Sie sich an das Lesen und Ausführen der Basisversion gewöhnt haben, tensorflow / models / embedding / word2vec.py. Sie können mit py fortfahren. Dies ist eine schwerere Implementierung und zeigt einige fortgeschrittenere TensorFlow-Prinzipien, z. B. das Verwenden von Threads zum effizienten Verschieben von Daten in ein Textmodell, das Erstellen von Prüfpunkten während des Trainings usw.

Aber zuerst schauen wir uns die Gründe für das Einbetten von Wörtern an. Wenn Sie ein Einbettungsprofi sind, können Sie diesen Abschnitt überspringen und auf die Details eingehen.

Motivation: Warum lernen, Wörter einzubetten?

Bild- oder Audioverarbeitungssysteme arbeiten mit reichhaltigen, hochdimensionalen Datensätzen, die als Vektoren einzelner Rohpixelintensitäten von Bilddaten oder beispielsweise Vektoren von Leistungsspektraldichtekoeffizienten von Audiodaten codiert sind. Bei Aufgaben wie Objekterkennung und Spracherkennung werden alle Informationen, die zur erfolgreichen Ausführung der Aufgabe erforderlich sind (da diese Aufgaben aus Rohdaten ausgeführt werden können), in den Daten codiert. Ich verstehe. Verarbeitungssysteme in natürlicher Sprache behandeln Wörter jedoch traditionell als einzelne Atomsymbole, wie "Katze" als "Id537" und "Hund" als "Id143". Diese Codierungen sind willkürlich und liefern dem System keine nützlichen Informationen über die Beziehungen, die zwischen den einzelnen Symbolen bestehen können. Mit anderen Worten, was das Modell über "Katzen" lernt, kann kaum zur Verarbeitung von Daten über "Hunde" verwendet werden (z. B. beide Tiere, vier Beine, Haustiere usw.). Darüber hinaus führt die Darstellung von Wörtern mit eindeutigen und diskreten IDs zu spärlichen Daten, was häufig bedeutet, dass mehr Daten benötigt werden, um statistische Modelle erfolgreich zu trainieren. Vektordarstellungen können verwendet werden, um einige dieser Hindernisse zu überwinden.

図

Das Vektorraummodell (https://en.wikipedia.org/wiki/Vector_space_model) (VSM) ordnet semantisch ähnliche Wörter benachbarten Punkten zu ("Punkte sind nahe beieinander eingebettet"). ), Stellt ein (eingebettetes) Wort in einem kontinuierlichen Vektorraum dar. In NLP hat VSM eine lange und reiche Geschichte, aber alle Methoden stehen der Verteilungshypothese (https://en.wikipedia.org/wiki/Distributional_semantics#Distributional_Hypothesis) (Verteilungshypothese) auf unterschiedliche Weise zur Verfügung. Hängt davon ab. Die Verteilungshypothese lautet, dass Wörter, die im selben Kontext vorkommen, eine semantische Bedeutung haben. Ansätze, die dieses Prinzip verwenden, können in zwei Kategorien unterteilt werden: zählbasierte Methoden (z. B. potenzielle semantische Analyse (https://en.wikipedia.org/wiki/Latent_semantic_analysis)) und Vorhersagen. (Zum Beispiel Neuronale probabilistische Sprachmodelle).

Diese Unterscheidung wird von Baroni et al. ausführlicher beschrieben. Apropos: Die zählbasierte Methode ist eine Methode zur Berechnung von Statistiken darüber, wie oft ein Wort zusammen mit seinen Nachbarn in einem großen Textkorpus vorkommt, und zur Zuordnung dieser Zählstatistiken zu einem kleinen, dichten Vektor jedes Wortes. Das Vorhersagemodell versucht also, Wörter direkt aus benachbarten Wörtern unter Verwendung eines kleinen, dichten eingebetteten Vektors vorherzusagen, der trainiert wurde (was als Parameter des Modells betrachtet wird).

Word2vec ist ein besonders rechnerisch effizientes Vorhersagemodell zum Lernen der Worteinbettung aus Rohtext. Es gibt zwei Typen: das CBOW-Modell (Continuous Word Set Model) und das Skipgram-Modell. Diese Modelle sind algorithmisch ähnlich, aber CBOW sagt das Zielwort (z. B. "mat") aus dem ursprünglichen Kontextwort ("cat sit") voraus, und skipgram sagt umgekehrt das Original aus dem Zielwort voraus. Sagen Sie kontextbezogene Wörter voraus. Diese Inversion mag als Option erscheinen, aber statistisch gesehen bewirkt CBOW, dass viele Verteilungsinformationen geglättet werden (indem der gesamte Kontext als eine einzige Beobachtung behandelt wird). In den meisten Fällen hat sich CBOW in kleineren Datensätzen als nützlich erwiesen. Skipgramme hingegen behandeln jedes Kontext- / Zielwortpaar als neue Beobachtung, die für größere Datensätze tendenziell besser ist. Von nun an konzentriert sich dieses Tutorial auf das Skipgramm-Modell.

Skalieren Sie mit Lärmschutztraining

Das neuronale probabilistische Sprachmodell verwendet traditionell die Wahrscheinlichkeit des nächsten Wortes $ w_t $ (t in "Ziel") aus mehreren Wörtern $ h $ (h in "Geschichte"), die bereits erschienen sind [Softmax-Funktion]. Trainieren Sie mit der Methode Most Probable (ML) für (https://en.wikipedia.org/wiki/Softmax_function).

P(w_t | h) = \text{softmax}(\text{score}(w_t, h)) \\
           = \frac{\exp\{\text{score}(w_t, h)\}}
             {\sum_\text{Word w' in Vocab} \exp \{ \text{score}(w', h) \} }.

Hier berechnet $ \ text {score} (w_t, h) $ die Kompatibilität des Wortes $ w_t $ mit dem Kontext $ h $ (im Allgemeinen nach internem Produkt). Trainieren Sie dieses Modell, indem Sie die Protokollwahrscheinlichkeit des Trainingssatzes maximieren. Maximieren Sie also Folgendes:

 J_\text{ML} = \log P(w_t | h) \\
  = \text{score}(w_t, h) -
     \log \left( \sum_\text{Word w' in Vocab} \exp \{ \text{score}(w', h) \} \right)

Dies ergibt ein gut normalisiertes Wahrscheinlichkeitsmodell für die Sprachmodellierung. Dies liegt jedoch daran, dass bei jedem Lernschritt jede Wahrscheinlichkeit unter Verwendung der Bewertungen aller anderen $ V $ -Wörter $ w '$ im aktuellen Kontext $ h $ berechnet und normalisiert werden muss. Es ist sehr teuer.

図

Andererseits erfordert das Lernen von Merkmalen mit word2vec kein vollständiges Wahrscheinlichkeitsmodell. Die CBOW- und Skipgram-Modelle verwenden stattdessen die binäre Notationsmethode, um das tatsächliche Zielwort $ w_t $ aus $ k $ virtuellen (Rausch-) Wörtern $ \ tilde w $ im selben Kontext zu identifizieren. Es wird mit logistischer Regression trainiert. Dies wird für das CBOW-Modell erläutert. Bei Überspringgrammen wird die Ausrichtung einfach umgedreht.

図

Mathematisch besteht der Zweck (für jedes Beispiel) darin, Folgendes zu maximieren:

J_\text{NEG} = \log Q_\theta(D=1 |w_t, h) +
  k \mathop{\mathbb{E}}_{\tilde w \sim P_\text{noise}}
     \left[ \log Q_\theta(D = 0 |\tilde w, h) \right]

Wobei $ Q_ \ theta (D = 1 | w, h) $ die Wahrscheinlichkeit lernt, dass das Wort $ w $ im Kontext $ h $ im Datensatz $ D $ unter dem Modell erscheint. Berechnet für den Vektor $ \ theta $. Es nähert sich tatsächlich dem erwarteten Wert an, indem ein $ k $ -Steuerwort aus der Rauschverteilung gezogen wird (dh der [Monte-Carlo-Mittelwert] berechnet wird (https://en.wikipedia.org/wiki/Monte_Carlo_integration)).

Diese Zielfunktion wird maximiert, wenn das Modell wahren Wörtern hohe Wahrscheinlichkeiten und falschen Wörtern niedrige Wahrscheinlichkeiten zuweist. Technisch wird dies als [negative Beispielstichprobe] bezeichnet (http://papers.nips.cc/paper/5021-distributed-representations-of-words-and-phrases-and-their-compositionality.pdf). Es gibt eine gute mathematische Motivation, diese Verlustfunktion zu verwenden: Die von dieser Methode vorgeschlagene Aktualisierung nähert sich der Aktualisierung der Softmax-Funktion im Extremfall. Die Berechnung der Verlustfunktion ist jedoch besonders attraktiv, da sie proportional zur Anzahl der ausgewählten $ k $ Rauschwörter und nicht zur $ V $ aller Wörter im Vokabular ist. Dies macht das Training viel schneller. Tatsächlich ist es sehr ähnlich Noise Control Assessment (NCE) Verwenden Sie Verlust. TensorFlow verfügt über eine praktische Hilfsfunktion tf.nn.nce_loss ().

Nun wollen wir sehen, wie das tatsächlich funktioniert!

Skipgramm-Modell

Betrachten Sie als Beispiel den folgenden Datensatz.

the quick brown fox jumped over the lazy dog

Erstens bildet es einen Datensatz von Wörtern und den Kontext, in dem sie erscheinen. Sie können einen "Kontext" auf jede sinnvolle Weise definieren. Tatsächlich ist der syntaktische Kontext (dh die syntaktische Abhängigkeit des aktuell anvisierten Wortes [Levy et al.]) (Https://levyomer.files.wordpress.com/2014/04/dependency-based-word- Siehe Embeddings-acl-2014.pdf)), mehrere Wörter auf der linken Seite des Ziels, mehrere Wörter auf der rechten Seite des Ziels usw. wurden berücksichtigt. Nehmen wir hier eine einfache Definition und definieren "Kontext" als Fenster mit mehreren Wörtern links und rechts vom Zielwort. Bei Verwendung der Fenstergröße 1 erhalten Sie das folgende Datensatzpaar (Kontext, Ziel).

([the, brown], quick), ([quick, fox], brown), ([brown, jumped], fox), ...

Denken Sie daran, dass Skipgram den Kontext und das Ziel invertiert und versucht, jedes Kontextwort aus dem Zielwort vorherzusagen. Daher besteht die Aufgabe darin, "das" und "braun" von "schnell" und "schnell" und "Fuchs" von "braun" vorherzusagen. Daher ist der Datensatz das folgende Paar (Eingabe, Ausgabe).

(quick, the), (quick, brown), (brown, quick), (brown, fox), ...

Die Zielfunktion wird im gesamten Datensatz definiert, verwendet jedoch im Allgemeinen jeweils eine Stichprobe (oder eine "Mini-Charge" von Stichproben mit Batchgröße, wobei 16 <= Batchgröße <= 512) im Allgemeinen [ Optimieren Sie dies mit Probabilistic Gradient Descent (https://en.wikipedia.org/wiki/Stochastic_gradient_descent) (SGD). Schauen wir uns einen Schritt in diesem Prozess an.

Stellen Sie sich vor, Sie beobachten den ersten Trainingsfall oben im Trainingsschritt $ t $. Das Ziel hier ist es, "das" von "schnell" vorherzusagen. Wählen Sie num_noise Noise (Control) Samples aus, indem Sie aus einer Rauschverteilung, normalerweise einer Unigrammverteilung, $ P (w) $, ziehen. Setzen Sie der Einfachheit halber num_noise = 1 und wählen Sie "Schaf" als Rauschprobe. Als nächstes berechnen wir den Verlust dieses beobachteten Sample-Noise-Sample-Paares, dh die Zielfunktion in Schritt $ t $ ist:

J^{(t)}_\text{NEG} = \log Q_\theta(D=1 | \text{the, quick}) +
  \log(Q_\theta(D=0 | \text{sheep, quick}))

Ziel ist es, den eingebetteten Parameter $ \ theta $ zu aktualisieren, um diese Zielfunktion zu verbessern (in diesem Fall zu maximieren). Wir tun dies, indem wir die Steigung des Verlusts für den eingebetteten Parameter $ \ theta $ ableiten, dh $ \ frac {\ partiell} {\ partiell \ theta} J_ \ text {NEG} $ (Glück) TensorFlow bietet dazu auch eine einfache Hilfsfunktion. Aktualisieren Sie dann die Einbettung, indem Sie kleine Schritte in Richtung des Verlaufs ausführen. Das Wiederholen dieses Vorgangs über den gesamten Trainingssatz hat den Effekt, dass der eingebettete Vektor für jedes Wort "bewegt" wird, bis es dem Modell gelingt, das tatsächliche Wort aus dem Rauschwort zu identifizieren.

Sie können den trainierten Vektor visualisieren, indem Sie ihn in zwei Dimensionen projizieren, z. B. mit Methode zur Reduzierung der t-SNE-Dimension. Ein genauerer Blick auf diese Visualisierungen zeigt, dass der Vektor allgemeine und praktisch sehr nützliche semantische Informationen über Wörter und ihre Beziehungen zueinander erfasst. Zuerst wurde entdeckt, dass eine bestimmte Richtung innerhalb des abgeleiteten Vektorraums für eine bestimmte semantische Beziehung spezifisch ist, beispielsweise das Geschlecht von Männern und Frauen und die Beziehung zwischen den Wörtern des Landes und der Hauptstadt, wie in der folgenden Abbildung gezeigt. Es war sehr interessant, als ich es tat (siehe auch Mikolov et al., 2013).

図

Dies erklärt, warum diese Vektoren als Merkmale in vielen Standard-NLP-Vorhersageaufgaben wie Teilwort-Tagging und Eigenausdruckerkennung nützlich sind ([Collobert et al., 2011](https: :). Originalrecherche von //arxiv.org/abs/1103.0398) (pdf) und [Turian et al., 2010](http: // www. Siehe Follow-up von aclweb.org/anthology/P10-1040)).

Aber hier wollen wir sie einfach verwenden, um hübsche Bilder zu zeichnen!

Erstellen eines Diagramms

Das ist alles über das Einbetten. Definieren wir nun eine eingebettete Matrix. Dies ist zunächst eine große Zufallsmatrix. Initialisieren Sie den Wert mit einer einheitlichen Zufallszahl.

embeddings = tf.Variable(
    tf.random_uniform([vocabulary_size, embedding_size], -1.0, 1.0))

Definiert den Verlust der Lärmschutzbewertung für ein logistisches Regressionsmodell. Aus diesem Grund müssen wir Gewichte und Verzerrungen für jedes Wort im Vokabular definieren ("Ausgabegewichte" im Gegensatz zu "Eingabeeinbettung" genannt). Jetzt definieren wir es.

nce_weights = tf.Variable(
  tf.truncated_normal([vocabulary_size, embedding_size],
                      stddev=1.0 / math.sqrt(embedding_size)))
nce_biases = tf.Variable(tf.zeros([vocabulary_size]))

Nachdem Sie die Parameter definiert haben, können Sie ein Diagramm für das Skipgram-Modell definieren. Nehmen wir zur Vereinfachung an, dass jedes Wort im Vokabular als Ganzzahl dargestellt wird und der Textkorpus bereits ganzzahlig ist (weitere Informationen [tensorflow / https: //www.tensorflow.org/versions/master/tutorials]). /word2vec/index.html/tutorials/word2vec/word2vec_basic.py](siehe https://tensorflow.googlesource.com/tensorflow/+/master/tensorflow/g3doc/tutorials/word2vec/word2vec_basic.py). Das Skipgramm-Modell akzeptiert zwei Eingaben. Einer ist ein Stapel, der mit ganzen Zahlen gefüllt ist, die das Quellkontextwort darstellen, und der andere ist für das Zielwort. Erstellen wir einen Platzhalterknoten für diese Eingaben, damit wir später Daten senden können.

# Placeholders for inputs
train_inputs = tf.placeholder(tf.int32, shape=[batch_size])
train_labels = tf.placeholder(tf.int32, shape=[batch_size, 1])

Was wir hier tun müssen, ist, den Vektor für jedes Quellwort im Stapel nachzuschlagen. TensorFlow hat einen praktischen Helfer, um dies zu vereinfachen.

embed = tf.nn.embedding_lookup(embeddings, train_inputs)

OK, jetzt, da Sie jedes Wort eingebettet haben, versuchen wir, das Zielwort mithilfe der Zielfunktion des Lärmschutztrainings vorherzusagen.

# Compute the NCE loss, using a sample of the negative labels each time.
loss = tf.reduce_mean(
  tf.nn.nce_loss(nce_weights, nce_biases, embed, train_labels,
                 num_sampled, vocabulary_size))

Jetzt, da wir einen Knoten für den Verlust haben, müssen wir weitere Knoten hinzufügen, z. B. den Gradienten berechnen und die Parameter aktualisieren. Wir verwenden dafür einen probabilistischen Gradientenabstieg, aber TensorFlow hat auch einen praktischen Helfer, um dies zu vereinfachen.

# We use the SGD optimizer.
optimizer = tf.train.GradientDescentOptimizer(learning_rate=1.0).minimize(loss)

Modelltraining

Das Training des Modells ist einfach. Verwenden Sie feed_dict, um Daten an Platzhalter zu senden, und in einer Schleife mit diesen neuen Daten session.run Rufen Sie einfach /client.html#Session.run auf.

for inputs, labels in generate_batch(...):
  feed_dict = {training_inputs: inputs, training_labels: labels}
  _, cur_loss = session.run([optimizer, loss], feed_dict=feed_dict)

Ein vollständiges Codebeispiel finden Sie unter tensorflow / g3doc / tutorials / word2vec / word2vec_basic.py.

Visualisierung der trainierten Einbettung

Nach dem Training können Sie mit t-SNE trainierte Einbettungen visualisieren.

図

Es ist fertig! Wie erwartet bilden ähnliche Wörter schließlich nahe beieinander liegende Cluster. Eine umfangreichere word2vec-Implementierung, die die erweiterten Funktionen von TensorFlow weiter demonstriert, finden Sie unter tensorflow / models / embeddedding / word2vec.py. Siehe die Implementierung von /embedding/word2vec.py).

Bewertung der Einbettung: Analogie Argumentation

Das Einbetten ist nützlich für verschiedene Vorhersageaufgaben von NLP. Mangelnde Ausbildung in einem vollwertigen Sprach- oder Eigenausdrucksmodell. Eine einfache Möglichkeit zur Bewertung der Einbettung besteht darin, syntaktische oder semantische Beziehungen direkt vorherzusagen, z. B. "Was ist eine Königin für einen König für einen Vater?". Ist sie zu verwenden für. Dies wird als Analogie-Inferenz bezeichnet. Die Aufgabe wurde von Mikolov et al. und dem Datensatz eingeführt Sie können es hier herunterladen: https://word2vec.googlecode.com/svn/trunk/questions-words.txt

Um dies zu bewerten, bauen Sie build_eval_graph () in [tensorflow / models / embeddedding / word2vec.py] auf (https://tensorflow.googlesource.com/tensorflow/+/master/tensorflow/models/embedding/word2vec.py). Siehe und die Funktion eval ().

Die Wahl der Hyperparameter hat einen starken Einfluss auf die Genauigkeit dieser Aufgabe. Um bei dieser Aufgabe eine Leistung auf dem neuesten Stand der Technik zu erzielen, trainieren Sie einen sehr großen Datensatz, optimieren Sie die Hyperparameter sorgfältig und probieren Sie die Daten außerhalb des Umfangs dieses Lernprogramms aus. Sie müssen solche Tricks anwenden.

Implementierungsoptimierung

Diese einfache Implementierung zeigt die Flexibilität von TensorFlow. Das Ändern von Trainingszielen ist beispielsweise so einfach wie das Ersetzen des Aufrufs von tf.nn.nce_loss () durch eine Standardalternative wie tf.nn.sampled_softmax_loss (). Wenn Sie eine neue Idee für eine Verlustfunktion haben, können Sie manuell einen neuen Zielausdruck in TensorFlow schreiben und den Optimierer seine Ableitung berechnen lassen. Diese Flexibilität ist von unschätzbarem Wert, um verschiedene Ideen auszuprobieren und sie während der Erkundungsphase der Modellentwicklung für maschinelles Lernen schnell zu wiederholen.

Sobald Sie eine zufriedenstellende Modellstruktur haben, kann es sich lohnen, Ihre Implementierung für eine effizientere Ausführung zu optimieren (und mehr Daten in kürzerer Zeit abzudecken). Beispielsweise wird der naive Code in diesem Lernprogramm verlangsamt, da das TensorFlow-Backend Python zum Lesen und Bereitstellen von Datenelementen verwendet, was wenig Arbeit erfordert. Wenn Sie einen schwerwiegenden Engpass in den Eingabedaten Ihres Modells feststellen, wie unter Neue Datenformate (https://www.tensorflow.org/versions/master/how_tos/new_data_formats/index.html) beschrieben. Sie können auch einen benutzerdefinierten Datenleser für das Problem implementieren. Für das Skipgram-Modell beispielsweise tensorflow / models / embedding / word2vec.py Ich habe das schon gemacht.

Wenn Ihr Modell nicht mehr die E / A-Rate bestimmt und Sie dennoch mehr Leistung benötigen, gehen Sie zu Neue Operation hinzufügen (https://www.tensorflow.org/versions/master/how_tos/adding_an_op/index.html). Wie bereits erwähnt, können Sie noch mehr Leistung erzielen, indem Sie Ihren eigenen TensorFlow-Vorgang schreiben. Als Beispiel für Überspringgramme stellen wir wieder [tensorflow / models / embeddedding / word2vec_optimized.py] bereit (https://tensorflow.googlesource.com/tensorflow/+/master/tensorflow/models/embedding/word2vec_optimized.py). tun. Versuchen Sie, Benchmarking gegeneinander durchzuführen, um die Leistungsverbesserung in jeder Phase zu messen.

Fazit

Dieses Tutorial befasste sich mit dem word2vec-Modell, einem rechnerisch effizienten Modell zum Erlernen der Worteinbettung. Motiviert, warum das Einbetten nützlich ist, diskutierte effiziente Trainingstechniken und zeigte, wie all dies in TensorFlow implementiert werden kann. Insgesamt hoffen wir, dass wir zeigen konnten, wie TensorFlow die für frühe Experimente erforderliche Flexibilität und die für nachfolgende maßgeschneiderte optimierte Implementierungen erforderlichen Steuerungen bietet. Ich bin.

Recommended Posts

TensorFlow Tutorial-Vektordarstellung von Wörtern (Übersetzung)
Vektordarstellung einfacher Wörter: word2vec, GloVe
Übersetzung von scsi_mid_low_api.txt
TensorFlow Tutorial-Mandelbrot Set (Übersetzung)
TensorFlow Tutorial - TensorFlow Mechanics 101 (Übersetzung)
Tensorflow / Keras-Zusammenfassung
TensorFlow Tutorial-Bilderkennung (Übersetzung)
TensorFlow Tutorial-MNIST Daten herunterladen (Übersetzung)
Tensorflows praktische Bibliothek TF-Slim
Experiment zur Optimierung der Tensorflow-Daten
TensorFlow Tutorial-Sequenztransformationsmodell (Übersetzung)
Japanische Übersetzung des sysstat-Handbuchs
Japanische Übersetzung des Linux-Handbuchs
TensorFlow Tutorial-Convolution Neuronales Netz (Übersetzung)
Warum ist der verteilte Ausdruck von Wörtern für die Verarbeitung natürlicher Sprache wichtig?