5

Ich versuche, die Wortdarstellung des Imdb-Datensatzes "von Grund auf neu" durch die TensorFlow tf.nn.embedding_lookup() Funktion zu lernen. Wenn ich es richtig verstanden habe, muss ich eine Einbettungsschicht vor der anderen verborgenen Schicht einrichten, und wenn ich dann Gradientenabstieg durchführe, "lernt" die Schicht eine Wortdarstellung in den Gewichten dieser Schicht. Wenn ich dies jedoch versuche, erhalte ich einen Formfehler zwischen meiner Einbettungsschicht und der ersten vollständig verbundenen Schicht meines Netzwerks.Tensorflow embedding_lookup

def multilayer_perceptron(_X, _weights, _biases): 
    with tf.device('/cpu:0'), tf.name_scope("embedding"): 
     W = tf.Variable(tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0),name="W") 
     embedding_layer = tf.nn.embedding_lookup(W, _X)  
    layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(embedding_layer, _weights['h1']), _biases['b1'])) 
    layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, _weights['h2']), _biases['b2'])) 
    return tf.matmul(layer_2, weights['out']) + biases['out'] 

x = tf.placeholder(tf.int32, [None, n_input]) 
y = tf.placeholder(tf.float32, [None, n_classes]) 

pred = multilayer_perceptron(x, weights, biases) 
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred,y)) 
train_step = tf.train.GradientDescentOptimizer(0.3).minimize(cost) 

init = tf.initialize_all_variables() 

Der Fehler, den ich bekommen ist:

ValueError: Shapes TensorShape([Dimension(None), Dimension(300), Dimension(128)]) 
and TensorShape([Dimension(None), Dimension(None)]) must have the same rank 

Antwort

15

Der Formfehler entsteht, weil Sie einen zweidimensionalen Tensor verwenden, x zu Index in einer zweidimensionalen Einbettung Tensor W. Denken Sie an tf.nn.embedding_lookup() (und seine enge Cousine tf.gather()) als jede Integer-Wert i in x nehmen und durch die Zeile W[i, :] ersetzen. Aus der Fehlermeldung kann man schließen, dass n_input = 300 und embedding_size = 128. Im Allgemeinen ist das Ergebnis von tf.nn.embedding_lookup() Anzahl der Dimensionen gleich rank(x) + rank(W) - 1 & hellip; In diesem Fall 3. Der Fehler tritt auf, wenn Sie versuchen, dieses Ergebnis mit _weights['h1'] zu multiplizieren, was eine (zweidimensionale) Matrix ist.

Um diesen Code zu beheben, hängt es davon ab, was Sie versuchen, und warum Sie eine Matrix von Eingaben an die Einbettung übergeben. Eine gemeinsame Sache zu tun ist, Aggregat die Einbettungsvektoren für jedes Eingabebeispiel in eine einzelne Zeile pro Beispiel mit einer Operation wie tf.reduce_sum(). Zum Beispiel könnten Sie folgendermaßen vorgehen:

W = tf.Variable(
    tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0) ,name="W") 
embedding_layer = tf.nn.embedding_lookup(W, _X) 

# Reduce along dimension 1 (`n_input`) to get a single vector (row) 
# per input example. 
embedding_aggregated = tf.reduce_sum(embedding_layer, [1]) 

layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(
    embedding_aggregated, _weights['h1']), _biases['b1'])) 
+1

Danke! Ich denke tf.nn.reduce_sum sollte tf.reduce_sum sein? Wenn Sie die Dimension der Einbettungsschicht reduzieren möchten, wie haben Sie dann die Option gewählt, um zwischen "n_input = 300" und "embedding_size = 128" zu reduzieren? – nicolasdavid

+2

Sie haben Recht mit dem Tippfehler - korrigiert es oben, danke! Ich entschied mich dafür, entlang der 'n_input'-Dimension zu reduzieren, weil es wahrscheinlicher erschien, dass dies zu Ihrem Problem passt, und ich nahm an, dass (z. B.) die Reihenfolge der Eingaben nicht wichtig war. Es ist ziemlich typisch, dies für Bag-of-Word-Probleme zu tun. Sie könnten * entlang 'embedding_size' reduzieren, aber ich denke, das würde viele Informationen aus der Einbettung verlieren, also würde es wahrscheinlich nicht so gut funktionieren. – mrry

0

Eine weitere mögliche Lösung ist: Anstatt die Einbettung Vektoren des Hinzufügens, verketten diese Vektoren in einen einzigen Vektor und die Anzahl der Neuronen in der verborgenen Schicht erhöhen.
I verwendet:
embedding_aggregated = tf.reshape(embedding_layer, [-1, embedding_size * sequence_length])
Auch i die Anzahl der Neuronen in verborgener Schicht zu embedding_size * sequence_length geändert. Beobachtung: Genauigkeit verbessert auch bei der Verwendung von Verkettung statt Addition.