Parfois la forme d'un tenseur dépend de la valeur est calculée au moment de l'exécution. Prenons l'exemple suivant, où l' x
est défini comme un tf.placeholder()
de vecteur avec les quatre éléments:
x = tf.placeholder(tf.int32, shape=[4])
print x.get_shape()
# ==> '(4,)'
La valeur de x.get_shape()
est le statique de la forme de l' x
, et l' (4,
) signifie que c'est un vecteur de longueur 4. Maintenant, nous allons appliquer l' tf.unique()
op x
y, _ = tf.unique(x)
print y.get_shape()
# ==> '(?,)'
L' (?,)
signifie qu' y
est un vecteur de longueur inconnue. Pourquoi est-il inconnu? tf.unique(x)
retourne les valeurs uniques d' x
, et les valeurs de x
sont inconnus parce que c'est un tf.placeholder()
, donc il n'a pas une valeur jusqu'à ce que vous lui donnez. Voyons ce qui se passe si vous nourrissez deux valeurs différentes:
sess = tf.Session()
print sess.run(y, feed_dict={x: [0, 1, 2, 3]}).shape
# ==> '(4,)'
print sess.run(y, feed_dict={x: [0, 0, 0, 0]}).shape
# ==> '(1,)'
Espérons-le, il est clair qu'un tenseur peut avoir une statique et dynamique de la forme. La forme dynamique est toujours bien définies, il n'a pas d' ?
dimensions—mais la statique de la forme peut être moins spécifiques. C'est ce qui permet TensorFlow à l'appui des opérations comme l' tf.unique()
et tf.dynamic_partition()
, ce qui peut avoir des tailles variables de sorties, et sont utilisés dans des applications avancées.
Enfin, l' tf.shape()
op peuvent être utilisés pour obtenir la forme dynamique d'un tenseur et l'utiliser dans un TensorFlow calcul:
z = tf.shape(y)
print sess.run(z, feed_dict={x: [0, 1, 2, 3]})
# ==> [4]
print sess.run(z, feed_dict={x: [0, 0, 0, 0]})
# ==> [1]