raspberry - ¿Cómo entender la forma estática y la forma dinámica en TensorFlow?
tensorflow raspberry pi (2)
A veces, la forma de un tensor depende de un valor que se calcula en tiempo de ejecución.
Tomemos el siguiente ejemplo, donde
x
se define como un vector
tf.placeholder()
con cuatro elementos:
x = tf.placeholder(tf.int32, shape=[4])
print x.get_shape()
# ==> ''(4,)''
El valor de
x.get_shape()
es la forma estática de
x
, y
(4,
) significa que es un vector de longitud 4. Ahora apliquemos
tf.unique()
op a
x
y, _ = tf.unique(x)
print y.get_shape()
# ==> ''(?,)''
El
(?,)
Significa que
y
es un vector de longitud desconocida.
¿Por qué es desconocido?
tf.unique()
devuelve los valores únicos de
x
, y los valores de
x
son desconocidos porque es un
tf.placeholder()
, por lo que no tiene un valor hasta que lo alimente.
Veamos qué sucede si alimenta dos valores diferentes:
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,)''
Esperemos que esto deje en claro que un tensor puede tener una forma estática y dinámica diferente.
La forma dinámica siempre está completamente definida, ¿no tiene
?
dimensiones, pero la forma estática puede ser menos específica.
Esto es lo que permite que TensorFlow admita operaciones como
tf.unique()
y
tf.dynamic_partition()
, que pueden tener salidas de tamaño variable y se utilizan en aplicaciones avanzadas.
Finalmente, el
tf.shape()
op se puede usar para obtener la forma dinámica de un tensor y usarlo en un cálculo de TensorFlow:
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]
En las preguntas frecuentes de TensorFlow , dice:
En TensorFlow, un tensor tiene una forma estática (inferida) y una dinámica (verdadera). La forma estática se puede leer usando el método tf.Tensor.get_shape (): esta forma se infiere de las operaciones que se usaron para crear el tensor, y puede estar parcialmente completa. Si la forma estática no está completamente definida, la forma dinámica de un Tensor t puede determinarse evaluando tf.shape (t).
Pero todavía no puedo entender completamente la relación entre la forma estática y la forma dinámica. ¿Hay algún ejemplo que muestre sus diferencias? Gracias.
Está bien definido en la respuesta anterior, votó eso. Hay algunas observaciones más que experimenté, así que quiero compartirlas.
tf.Tensor.get_shape (), se puede usar para inferir la salida usando la operación que la creó, significa que podemos inferirla sin usar sess.run () (ejecutar la operación), como lo indica el nombre, forma estática. Por ejemplo,
c = tf.random_uniform ([1,3,1,1])
es un tf.Tensor, y queremos saber su forma en cualquier paso del código, antes de ejecutar el gráfico, para que podamos usar
c.get_shape ()
La razón por la cual tf.Tensor.get_shape no puede ser dinámico (sess.run ()) se debe al tipo de salida TensorShape en lugar de tf.tensor, y la salida de TensorShape restringe el uso de sess.run ().
sess.run (c.get_shape ())
si lo hacemos, recibimos un error de que TensorShape tiene un tipo no válido, debe ser un Tensor / operación o una cadena.
Por otro lado, la forma dinámica necesita que la operación se ejecute a través de sess.run () para obtener la forma
sess.run (tf.shape (c))
Salida: matriz ([1, 3, 1, 1])
o
sess.run (c) .shape
(1, 3, 1, 1) # tupla
Espero que ayude a aclarar los conceptos de tensorflow.