tf.nn.embedding_lookup(params, ids, partition_strategy='mod', name=None)
Ich kann die Pflicht dieser Funktion nicht verstehen. Ist es wie eine Nachschlagetabelle? Was bedeutet, die Parameter zurückzugeben, die jeder ID entsprechen (in IDs)?
skip-gram
Wenn wir zum Beispiel im Modell verwenden tf.nn.embedding_lookup(embeddings, train_inputs)
, findet es dann für jedes train_input
die entsprechende Einbettung?
Antworten:
embedding_lookup
Funktion ruft Zeilen desparams
Tensors ab. Das Verhalten ähnelt der Verwendung der Indizierung mit Arrays in Numpy. Z.Bparams
Argument kann auch eine Liste von Tensoren sein, in welchem Fall dieids
unter den Tensoren verteilt werden. Zum Beispiel, da eine Liste von 3 Tensoren[2, 64]
, das Standardverhalten ist , dass sie vertretenids
:[0, 3]
,[1, 4]
,[2, 5]
.partition_strategy
Steuert dieids
Verteilung der Daten auf die Liste. Die Partitionierung ist nützlich bei größeren Problemen, wenn die Matrix möglicherweise zu groß ist, um sie in einem Stück zu halten.quelle
select_rows
?embedding_lookup
bietet einfach eine bequeme (und parallele) Möglichkeit, Einbettungen abzurufen, die der ID in entsprechenids
. Derparams
Tensor ist normalerweise eine tf-Variable, die im Rahmen des Trainingsprozesses gelernt wird - eine tf-Variable, deren Komponenten direkt oder indirekt in einer Verlustfunktion (z. B.tf.l2_loss
) verwendet werden, die von einem Optimierer (z. B.tf.train.AdamOptimizer
) optimiert wird .Ja, diese Funktion ist schwer zu verstehen, bis Sie den Punkt bekommen.
In seiner einfachsten Form ähnelt es
tf.gather
. Es gibt die Elemente vonparams
gemäß den durch angegebenen Indizes zurückids
.Zum Beispiel (vorausgesetzt du bist drinnen
tf.InteractiveSession()
)würde zurückgeben
[10 20 30 40]
, weil das erste Element (Index 0) von Parametern ist10
, das zweite Element von Parametern (Index 1) ist20
usw.Ähnlich,
würde zurückkehren
[20 20 40]
.Aber
embedding_lookup
ist mehr als das. Dasparams
Argument kann eine Liste von Tensoren sein und nicht ein einzelner Tensor.In einem solchen Fall
ids
entsprechen die in angegebenen Indizes Elementen von Tensoren gemäß einer Partitionsstrategie , wobei die Standardpartitionsstrategie 'mod' ist.In der 'mod'-Strategie entspricht Index 0 dem ersten Element des ersten Tensors in der Liste. Index 1 entspricht dem ersten Element des zweiten Tensors. Index 2 entspricht dem ersten Element des dritten Tensors und so weiter. Einfach Index
i
entspricht für alle Indizes dem ersten Element des (i + 1) -ten Tensors0..(n-1)
, vorausgesetzt, params ist eine Liste vonn
Tensoren.Der Index
n
kann jetzt nicht dem Tensor n + 1 entsprechen, da die Listeparams
nurn
Tensoren enthält . Der Indexn
entspricht also dem zweiten Element des ersten Tensors. In ähnlicher Weisen+1
entspricht der Index dem zweiten Element des zweiten Tensors usw.Also im Code
Index 0 entspricht dem ersten Element des ersten Tensors: 1
Index 1 entspricht dem ersten Element des zweiten Tensors: 10
Index 2 entspricht dem zweiten Element des ersten Tensors: 2
Index 3 entspricht dem zweiten Element des zweiten Tensors: 20
Das Ergebnis wäre also:
quelle
partition_strategy='div'
und würden erhalten[10, 1, 10, 2, 10, 20]
, dhid=1
ist das zweite Element des ersten Parameters. Grundsätzlich:partition_strategy=mod
(Standard)id%len(params)
: Index des Parameters in Paramsid//len(params)
: Index des Elements im obigen Parameterpartition_strategy=*div*
umgekehrtJa, der Zweck der
tf.nn.embedding_lookup()
Funktion besteht darin, eine Suche in der Einbettungsmatrix durchzuführen und die Einbettungen (oder in einfachen Worten die Vektordarstellung) von Wörtern zurückzugeben.Eine einfache Einbettungsmatrix (mit Form :)
vocabulary_size x embedding_dimension
würde wie folgt aussehen. (dh jedes Wort wird durch einen Vektor von Zahlen dargestellt; daher der Name word2vec )Matrix einbetten
Ich habe die obige Einbettungsmatrix aufgeteilt und nur die Wörter geladen, in
vocab
denen sich unser Vokabular und die entsprechenden Vektoren imemb
Array befinden.Einbetten der Suche in TensorFlow
Jetzt werden wir sehen, wie wir eine Einbettungssuche für einen beliebigen Eingabesatz durchführen können.
Beobachten Sie anhand der Wortindizes in unserem Wortschatz, wie wir die Einbettungen aus unserer ursprünglichen Einbettungsmatrix (mit Wörtern) erhalten haben .
Normalerweise wird eine solche Einbettungssuche von der ersten Schicht (als Einbettungsschicht bezeichnet ) durchgeführt, die diese Einbettungen dann zur weiteren Verarbeitung an RNN / LSTM / GRU-Schichten weiterleitet.
Randnotiz : Normalerweise hat das Vokabular auch einen speziellen
unk
Token. Wenn also ein Token aus unserem Eingabesatz nicht in unserem Vokabular vorhanden ist, wird der entsprechende Indexunk
in der Einbettungsmatrix nachgeschlagen.PS Beachten Sie, dass dies
embedding_dimension
ein Hyperparameter ist, den man für seine Anwendung anpassen muss, aber beliebte Modelle wie Word2Vec und GloVe verwenden300
Dimensionsvektoren zur Darstellung jedes Wortes.Bonus Lesen word2vec Skip-Gramm-Modell
quelle
Hier ist ein Bild, das den Prozess des Einbettens der Suche zeigt.
Kurz gesagt, es erhält die entsprechenden Zeilen einer Einbettungsschicht, die durch eine Liste von IDs angegeben werden, und stellt diese als Tensor bereit. Dies wird durch den folgenden Prozess erreicht.
lookup_ids = tf.placeholder([10])
embeddings = tf.Variable([100,10],...)
embed_lookup = tf.embedding_lookup(embeddings, lookup_ids)
lookup = session.run(embed_lookup, feed_dict={lookup_ids:[95,4,14]})
quelle
Wenn sich der Parametertensor in hohen Dimensionen befindet, beziehen sich die IDs nur auf die obere Dimension. Vielleicht ist es für die meisten Leute offensichtlich, aber ich muss den folgenden Code ausführen, um das zu verstehen:
Nur die 'div'-Strategie auszuprobieren und für einen Tensor macht es keinen Unterschied.
Hier ist die Ausgabe:
quelle
Eine andere Sichtweise ist, dass Sie die Tensoren auf ein eindimensionales Array reduzieren und dann eine Suche durchführen
(zB) Tensor0 = [1,2,3], Tensor1 = [4,5,6], Tensor2 = [7,8,9]
Der abgeflachte Tensor ist wie folgt [1,4,7,2,5,8,3,6,9]
Wenn Sie nun [0,3,4,1,7] nachschlagen, wird [1,2,5,4,6] angezeigt.
(i, e) Wenn der Suchwert beispielsweise 7 ist und wir 3 Tensoren (oder einen Tensor mit 3 Zeilen) haben, dann
7/3: (Erinnerung ist 1, Quotient ist 2) Es wird also das 2. Element von Tensor1 angezeigt, nämlich 6
quelle
Da ich auch von dieser Funktion fasziniert war, gebe ich meine zwei Cent.
Ich sehe es im 2D-Fall nur als Matrixmultiplikation (es ist einfach, es auf andere Dimensionen zu verallgemeinern).
Betrachten Sie ein Vokabular mit N Symbolen. Dann können Sie ein Symbol x als einen Vektor der Dimensionen Nx1 darstellen, der einmalig codiert ist.
Sie möchten dieses Symbol jedoch nicht als Vektor von Nx1 darstellen, sondern als Vektor mit den Dimensionen Mx1, genannt y .
Um x in y umzuwandeln , können Sie die Matrix E mit den Dimensionen MxN verwenden und einbetten :
y = E x .
Dies ist im Wesentlichen das, was tf.nn.embedding_lookup (params, ids, ...) tut, mit der Nuance, dass ids nur eine Zahl sind, die die Position der 1 im One-Hot-Coded-Vektor x darstellt .
quelle
Das Hinzufügen zu Asher Sterns Antwort
params
wird als Partitionierung eines großen Einbettungstensors interpretiert . Es kann sich um einen einzelnen Tensor handeln, der den vollständigen Einbettungstensor darstellt, oder um eine Liste von X-Tensoren, die bis auf die erste Dimension alle dieselbe Form haben und Sharded-Einbettungstensoren darstellen.Die Funktion
tf.nn.embedding_lookup
wird unter Berücksichtigung der Tatsache geschrieben, dass die Einbettung (Parameter) groß ist. Deshalb brauchen wirpartition_strategy
.quelle