2016-06-27 6 views
7

Ich habe ein Problem mit dem ich gekämpft habe. Es ist verwandt mit tf.matmul() und seine Abwesenheit von Rundfunk.Keine Übertragung für tf.matmul in TensorFlow

Mir ist ein ähnliches Problem auf https://github.com/tensorflow/tensorflow/issues/216 bekannt, aber tf.batch_matmul() sieht nicht wie eine Lösung für meinen Fall aus.

Ich brauche meine Eingangsdaten als 4D-Tensor zu kodieren: X = tf.placeholder(tf.float32, shape=(None, None, None, 100)) Die erste Dimension die Größe einer Charge, die zweite die Anzahl der Einträge im Stapel. Sie können sich jeden Eintrag als eine Komposition aus einer Anzahl von Objekten vorstellen (dritte Dimension). Schließlich wird jedes Objekt durch einen Vektor von 100 Gleitkommawerten beschrieben.

Beachten Sie, dass ich None für die zweite und dritte Dimension verwendet habe, da sich die tatsächlichen Größen in jeder Charge ändern können. Aber der Einfachheit halber wollen wir den Tensor Form mit tatsächlichen Zahlen: X = tf.placeholder(tf.float32, shape=(5, 10, 4, 100))

Dies sind die Schritte meiner Berechnung:

  1. berechnen eine Funktion jedes Vektors von 100 Float-Werte (zB lineare Funktion) W = tf.Variable(tf.truncated_normal([100, 50], stddev=0.1)) Y = tf.matmul(X, W) Problem: kein Rundfunk für tf.matmul() und keinen Erfolg tf.batch_matmul() erwartete Form von Y unter Verwendung von: (5, 10, 4, 50)

  2. Anwendung durchschnittlichen Pooling für jeden Eintrag des Charge (über die Objekte jeden Eintrag): Y_avg = tf.reduce_mean(Y, 2) erwartete Form von Y_avg: (5, 10, 50)

I erwartet, dass tf.matmul() würde haben Rundfunk unterstützt. Dann habe ich tf.batch_matmul() gefunden, aber es sieht immer noch so aus, als ob es nicht auf meinen Fall zutrifft (z. B. muss W mindestens 3 Dimensionen haben, nicht klar warum).

BTW, oben habe ich eine einfache lineare Funktion verwendet (deren Gewichte in W gespeichert sind). Aber in meinem Modell habe ich stattdessen ein tiefes Netzwerk. Das allgemeinere Problem, das ich habe, ist das automatische Berechnen einer Funktion für jede Scheibe eines Tensors. Deshalb habe ich erwartet, dass tf.matmul() ein Broadcasting-Verhalten gehabt hätte (wenn ja, wäre vielleicht tf.batch_matmul() nicht einmal notwendig).

Freuen Sie sich darauf, von Ihnen zu lernen! Alessio

Antwort

5

Sie erreichen können, dass X durch Umformen [n, d] zu gestalten, wo d die Dimensionalität einer einzigen „Instanz“ ist der Berechnung (100 in Ihrem Beispiel) und n ist die Zahl jener Fälle, in Ihrem mehrdimensionale Objekt (5*10*4=200 in Ihrem Beispiel). Nach dem Umformen können Sie tf.matmul verwenden und dann wieder in die gewünschte Form umformen. Die Tatsache, dass die ersten drei Dimensionen variieren können, macht das ein wenig schwierig, aber Sie können tf.shape verwenden, um die tatsächlichen Formen während der Laufzeit zu bestimmen. Schließlich können Sie den zweiten Schritt Ihrer Berechnung durchführen, der ein einfacher tf.reduce_mean über die jeweilige Dimension sein sollte. Alles in allem würde es so aussehen:

X = tf.placeholder(tf.float32, shape=(None, None, None, 100)) 
W = tf.Variable(tf.truncated_normal([100, 50], stddev=0.1)) 
X_ = tf.reshape(X, [-1, 100]) 
Y_ = tf.matmul(X_, W) 
X_shape = tf.gather(tf.shape(X), [0,1,2]) # Extract the first three dimensions 
target_shape = tf.concat(0, [X_shape, [50]]) 
Y = tf.reshape(Y_, target_shape) 
Y_avg = tf.reduce_mean(Y, 2) 
+0

Danke für Ihre Antwort.Leider hat Ihre Lösung zwei Probleme: 1. es Durchschnittswerte über * alle * die Vektoren, die nicht korrekt ist 2. Umformung ist nur gültig im Fall eines festen Formtensors, während ich Chargen, in denen die ersten 3 Dimensionen haben variieren (festgelegt in jeder Charge, unterschiedlich in den Chargen) –

+0

Warum wird über alle Vektoren gemittelt? "X [i, j, k,:]" 'bildet einen einzelnen Vektor, richtig? Durch Umformung in der von mir vorgeschlagenen Weise stapeln wir diese Vektoren in einer großen Matrix (jede Zeile enthält einen der Vektoren). Wenn wir nun die Matrixmultiplikation durchführen, wird jede Zeile separat mit der Matrix multipliziert. Jetzt können wir mit jeder Zeile das, was gewünscht wird, machen (z. B. den Durchschnitt wie in Ihrem Beispiel nehmen) und dann zu der Form umsortieren, die wir haben wollen. Ich sehe nicht, wo wir einen Durchschnitt über die Vektoren nehmen, aber ich vermisse etwas. – lballes

+0

In Bezug auf das zweite Problem, so lange die Dimensionalität der Vektoren (100 in Ihrem Beispiel) festgelegt ist, sollte "tf.reshape (X, [-1, 100])" "gut funktionieren? Mit dem '' -1'' müssen die anderen Dimensionen nicht a priori geändert werden. – lballes

Verwandte Themen