我是TensorFlow的新手。在阅读现有文档时,我发现tensor
这个术语非常令人困惑。因此,我需要澄清以下几个问题:
tensor
与Variable
、tensor
与tf.constant
、’tensor’与tf.placeholder
之间的关系是什么?- 它们都是张量的类型吗?
回答:
TensorFlow没有一级张量对象,这意味着在运行时执行的基础图中没有Tensor
的概念。相反,图由相互连接的操作节点组成,代表操作。一个操作会为其输出分配内存,这些输出在端点:0
、:1
等处可用,您可以将每个这些端点视为一个Tensor
。如果您有一个对应于nodename:0
的tensor
,您可以通过sess.run(tensor)
或sess.run('nodename:0')
获取其值。执行的粒度发生在操作级别,因此run
方法将执行操作,这将计算所有的端点,而不仅仅是:0
端点。可能存在没有输出的操作节点(如tf.group
),在这种情况下,没有与之关联的张量。没有底层操作节点是不可能有张量的。
您可以通过执行以下操作来检查基础图中发生的情况
tf.reset_default_graph()value = tf.constant(1)print(tf.get_default_graph().as_graph_def())
因此,使用tf.constant
您会得到一个单一的操作节点,您可以使用sess.run("Const:0")
或sess.run(value)
来获取它
同样,value=tf.placeholder(tf.int32)
创建一个名为Placeholder
的常规节点,您可以将其作为feed_dict={"Placeholder:0":2}
或feed_dict={value:2}
输入。您不能在同一个session.run
调用中同时输入和获取占位符,但您可以通过在其上附加一个tf.identity
节点并获取该节点来查看结果。
对于变量
tf.reset_default_graph()value = tf.Variable(tf.ones_initializer()(()))value2 = value+3print(tf.get_default_graph().as_graph_def())
您会看到它创建了两个节点Variable
和Variable/read
,这两个节点的:0
端点都是有效的值可以获取。然而,Variable:0
具有特殊的ref
类型,意味着它可以用作变异操作的输入。Python调用tf.Variable
的结果是一个PythonVariable
对象,并且有一些Python魔法来根据是否需要变异来替换Variable/read:0
或Variable:0
。由于大多数操作只有一个端点,:0
会被省略。另一个例子是Queue
—— close()
方法将创建一个新的Close
操作节点,该节点连接到Queue
操作。为了总结 —— 对像Variable
和Queue
这样的Python对象的操作会根据使用情况映射到不同的底层TensorFlow操作节点上。
对于像tf.split
或tf.nn.top_k
这样的操作,它们创建具有多个端点的节点,Python的session.run
调用会自动将输出包装在tuple
或collections.namedtuple
中的Tensor
对象中,这些对象可以单独获取。