2016-05-08 166 views
18

TensorFlow FAQ,它说:如何理解TensorFlow中的静态形状和动态形状?

在TensorFlow,张量既有静态(推断)的形状和 动态(真)的形状。可以使用tf.Tensor.get_shape()方法读取静态形状:此形状从用于创建张量的 操作推断,并且可能部分完成 。如果静态形状未完全定义,则可以通过评估tf.shape(t)来确定张量t的动态形状 。

但是我仍然不能完全理解静态形状和动态形状之间的关系。是否有任何示例显示其差异?谢谢。

回答

27

有时,张量的形状取决于在运行时计算的值。让我们以下面的例子,其中x与四个元素定义为tf.placeholder()向量:

x = tf.placeholder(tf.int32, shape=[4]) 
print x.get_shape() 
# ==> '(4,)' 

x.get_shape()的值是x静态形状,并且(4,)意味着它是一个长度为4的矢量。现在,让我们的tf.unique()运算应用到x

y, _ = tf.unique(x) 
print y.get_shape() 
# ==> '(?,)' 

(?,)意味着y未知长度的向量。为什么它是未知的? tf.unique(x)返回来自x的唯一值,并且x的值未知,因为它是tf.placeholder(),所以它只有在提供它之前才具有值。让我们来看看,如果你给两个不同的值会发生什么:

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,)' 

希望这清楚地表明,张量可以有不同的静态和动态形状。动态形状始终完全定义—它没有?尺寸—但静态形状可能不太具体。这允许TensorFlow支持像tf.unique()tf.dynamic_partition()这样的操作,它可以具有可变大小的输出,并用于高级应用程序。

最后,tf.shape()运算可以用来获得张量的动态形状,并在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] 
+0

我可以使用动态形状与可学习几层?如果我使用较小的输入,会发生什么? – nouveau

+3

通常,可学习参数的形状需要静态知道,但输入可以具有可变的批量大小。 – mrry