2016-08-06 8 views
5

Ich habe eine Variable a der Dimension (1, 5), die ich so oft wie die Größe meiner Mini-Charge "Kacheln" möchte. Zum Beispiel, wenn die Minibatchgröße 32 ist, dann möchte ich einen Tensor c der Dimension (32, 5) konstruieren, wobei jede Zeile dieselben Werte wie die ursprüngliche (1, 5) Variable a hat.Tensorflow Form eines gekachelten Tensors

Aber ich kenne nur die Mini-Losgröße zur Laufzeit: Es ist die Größe der Dimension 0 von Platzhalter b: tf.shape(b)[0]

Hier ist mein Code c zu konstruieren:

a = tf.Variable(np.random.uniform(size=(1,5))) 
b = tf.placeholder(shape=[None, 12], dtype=tf.float32) 
batch_size = tf.shape(b)[0] 
c = tf.tile(a, tf.pack([batch_size, 1])) 

Das läuft gut . Jedoch gibt c.get_shape() zurück (?,?). Ich verstehe nicht, warum das nicht zurückkehrt (?, 5).

Das verursacht ein Problem später in meinem Code, wenn ich eine Matrixvariable W mit der Anzahl der Spalten konstruiere, von denen ich erwarte, 5 anstelle von?.

Jede Hilfe wäre willkommen. Vielen Dank.

+0

Welche Version? Ein ähnliches Problem wurde in 0.10rc behandelt. Sie können set_shape auch als Workaround verwenden –

+0

Danke, set_shape erledigt den Job. . Ist Version 0.8.0rc0. –

Antwort

3

[EDIT: Dies wurde in einem commit zu TensorFlow am 10. August fixiert, 2016.]

Dies ist eine bekannte Begrenzung der TensorFlow der Form Inferenz: wenn das multiples Argument tf.tile() ist ein berechneter Wert (z (als Ergebnis von tf.pack() hier), und sein Wert ist nicht trivial berechenbar in Graphenbauzeit (in diesem Fall, weil es auf tf.placeholder(), die keinen Wert hat, bis es zugeführt wird), wird die aktuelle Form Inferenz seine Hände werfen und erkläre, dass die Form unbekannt ist (aber mit dem gleichen Rang wie die Eingabe, a).

Die aktuelle Problemumgehung besteht darin, Tensor.set_shape() zu verwenden, die es Ihnen als Programmierer ermöglicht, zusätzliche Forminformationen bereitzustellen, wenn Sie mehr als die Formschlussfolgerung wissen. Zum Beispiel könnten Sie tun:

a = tf.Variable(np.random.uniform(size=(1, 5))) 
b = tf.placeholder(shape=[None, 12], dtype=tf.float32) 
batch_size = tf.shape(b)[0] 
c = tf.tile(a, tf.pack([batch_size, 1])) 
c.set_shape([None, a.get_shape()[1]]) # or `c.set_shape([None, 5])` 

Allerdings haben wir vor kurzem einige Features, die es möglich machen, zu propagieren teilweise berechneten Werte, die als Formen verwendet werden können, und dies kann die Formfunktion zu unterstützen für tf.tile() angepasst werden. Ich habe eine GitHub issue erstellt, um dies zu verfolgen, und ich habe ein Update, das gerade getestet wird.

+0

Die Arbeit macht den Job. Vielen Dank, besonders für die ausführliche Erklärung. –

+0

Beachten Sie, dass 'pack' durch' stack' ersetzt wurde –