TensorFlow tutorial sagt, dass zum Zeitpunkt der Erstellung müssen wir die Form der Tensoren angeben. Diese Form wird automatisch zur Form des Tensors. Es sagt auch, dass TensorFlow erweiterte Mechanismen zur Umformung von Variablen bietet. Wie kann ich das machen? Irgendein Codebeispiel?Wie kann ich die Form einer Variablen in TensorFlow ändern?
Antwort
Werfen Sie einen Blick auf shapes-and-shaping von TensorFlow Dokumentation. Es beschreibt verschiedene verfügbare Formtransformationen.
Die gebräuchlichste Funktion ist wahrscheinlich tf.reshape, die ihrem äquivalenten Äquivalent ähnlich ist. Damit können Sie jede gewünschte Form angeben, solange die Anzahl der Elemente gleich bleibt. In der Dokumentation finden Sie einige Beispiele.
Documentation shows Methoden für die Umformung. Sie sind:
- Squeeze umformen (entfernt Dimensionen der Größe 1 aus der Form eines Tensor)
- expand_dims (fügt Dimensionen der Größe 1)
sowie Bündel von Methoden zu bekommen shape
, size
, rank
von Ihrem Tensor. Wahrscheinlich das am häufigsten verwendeten ist reshape
und hier ist ein Codebeispiel mit einem paar Grenzfällen (-1):
import tensorflow as tf
v1 = tf.Variable([
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
])
v2 = tf.reshape(v1, [2, 6])
v3 = tf.reshape(v1, [2, 2, -1])
v4 = tf.reshape(v1, [-1])
# v5 = tf.reshape(v1, [2, 4, -1]) will fail, because you can not find such an integer for -1
v6 = tf.reshape(v1, [1, 4, 1, 3, 1])
v6_shape = tf.shape(v6)
v6_squeezed = tf.squeeze(v6)
v6_squeezed_shape = tf.shape(v6_squeezed)
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
a, b, c, d, e, f, g = sess.run([v2, v3, v4, v6, v6_shape, v6_squeezed, v6_squeezed_shape])
# print all variables to see what is there
print e # shape of v6
print g # shape of v6_squeezed
Die tf.Variable
Klasse ist die empfohlene Methode, Variablen zu erstellen, aber es schränkt die Fähigkeit, die Form zu ändern der Variablen, sobald sie erstellt wurde.
Wenn Sie die Form einer Variablen ändern müssen, können Sie das folgende (zB für eine 32-Bit-Gleitkomma-Tensor) tun:
var = tf.Variable(tf.placeholder(tf.float32))
# ...
new_value = ... # Tensor or numpy array.
change_shape_op = tf.assign(var, new_value, validate_shape=False)
# ...
sess.run(change_shape_op) # Changes the shape of `var` to new_value's shape.
Beachten Sie, dass diese Funktion nicht in der dokumentierten öffentlichen API ist Es unterliegt Änderungen. Wenn Sie feststellen, dass Sie diese Funktion nutzen müssen, lassen Sie es uns wissen und wir können nach Wegen suchen, wie Sie diese Funktion unterstützen können.
tf.Variable(tf.placeholder(tf.float32))
ist nicht gültig bei tensorflow 1.2.1
in Python-Shell:
import tensorflow as tf
tf.Variable(tf.placeholder(tf.float32))
erhalten Sie:
ValueError: initial_value must have a shape specified: Tensor("Placeholder:0", dtype=float32)
Update: wenn Sie validate_shape=False
hinzufügen, wird es sei kein Fehler.
tf.Variable(tf.placeholder(tf.float32), validate_shape=False)
wenn tf.py_func
entspricht Ihrer Anforderung:
def init():
return numpy.random.rand(2,3)
a = tf.pyfun(init, [], tf.float32)
Sie Variable, die eine beliebige Form hat erstellen können, indem Sie Ihre eigene init-Funktion übergeben.
Ein anderer Weg:
var = tf.get_varible('my-name', initializer=init, shape=(1,1))
Sie tf.constant
passieren kann oder jede init
Funktion, die numpy Array zurückgibt. Die angegebene Form wird nicht validiert. Die Ausgabeform ist Ihre tatsächliche Datenform.
Das Problem mit diesem Ansatz ist, dass 'var.shape' nicht entsprechend aktualisiert wird. Dies bleibt beim Speichern eines Prüfpunkts bestehen und verhindert somit das erneute Laden des Prüfpunkts, da die variable Form nicht mit der Gewichtsform übereinstimmt. Gibt es eine Möglichkeit, 'var.shape' zu aktualisieren? Soll ich ein GitHub-Problem erstellen? –
Ich fand diesen Thread und diskutierte das Problem: https://github.com/tensorflow/tensorflow/issues/10091#issuecomment-304301817 Ich frage mich jedoch, ob es eine Möglichkeit gibt, die Gewichte bestehender Netzwerke zu erweitern –