在TensorFlow中,Session.run()和Tensor.eval()有什么区别?

223

TensorFlow 有两种计算图中部分节点的方法:Session.runTensor.eval。这两种方式之间是否有差别?


1
完整的命名空间是 tf.Tensor.eval()tf.Session.run(),但是它们之间有联系,即 tf.Operation.run()tf.Tensor.eval(),如此解释在这里 - prosti
6个回答

250
如果您有一个张量t,调用t.eval()等同于调用tf.get_default_session().run(t)
您可以按照以下方式设置会话为默认值:
t = tf.constant(42.0)
sess = tf.Session()
with sess.as_default():   # or `with sess:` to close on exit
    assert sess is tf.get_default_session()
    assert t.eval() == sess.run(t)

最重要的区别是你可以使用sess.run()在同一步骤中获取多个张量的值:

t = tf.constant(42.0)
u = tf.constant(37.0)
tu = tf.mul(t, u)
ut = tf.mul(u, t)
with sess.as_default():
   tu.eval()  # runs one step
   ut.eval()  # runs one step
   sess.run([tu, ut])  # evaluates both tensors in a single step

请注意,每次调用evalrun都会从头开始执行整个图。要缓存计算结果,请将其分配给tf.Variable

1
第二个例子有什么不同吗?只是你可以评估分开的操作(或图形?不确定区别是什么)吗? - Charlie Parker
1
等一下,你的例子能运行吗?我尝试了:a = tf.constant(2.0) b = tf.constant(3.0) ab = tf.matmul(a, b),但是tensorflow报错说形状不匹配,更准确地说,应该至少是2维。 - Charlie Parker
@Pinocchio 我认为API已经改变了,因为原来的答案是4年前发布的。我使用了 tf.multiply(t, u),它可以正常工作。 - yuqli

44

关于TensorFlow的常见问题,这里有一个与这个问题完全相同的答案。我会将其放在这里:


如果t是一个Tensor对象,那么t.eval()等同于sess.run(t)(其中sess是当前默认的会话)。以下两段代码是等价的:

sess = tf.Session()
c = tf.constant(5.0)
print sess.run(c)

c = tf.constant(5.0)
with tf.Session():
  print c.eval()

在第二个例子中,会话作为上下文管理器,这样它就会在with块的生命周期内安装为默认会话。上下文管理器方法可以在简单用例(如单元测试)中导致更简洁的代码;如果您的代码涉及多个图形和会话,则明确调用Session.run()可能更直接。
我建议您至少浏览整个常见问题解答,因为它可能会澄清很多事情。

2

eval()无法处理列表对象

tf.reset_default_graph()

a = tf.Variable(0.2, name="a")
b = tf.Variable(0.3, name="b")
z = tf.constant(0.0, name="z0")
for i in range(100):
    z = a * tf.cos(z + i) + z * tf.sin(b - i)
grad = tf.gradients(z, [a, b])

init = tf.global_variables_initializer()

with tf.Session() as sess:
    init.run()
    print("z:", z.eval())
    print("grad", grad.eval())

但是Session.run()可以

print("grad", sess.run(grad))

如果我说错了,请纠正我。


1

记住最重要的一点:

从TenorFlow获取一个常量、变量(任何结果)的唯一方法是使用会话。

知道这一点,其他所有内容都容易理解:

无论是tf.Session.run()还是tf.Tensor.eval()都可以从会话中获取结果,其中tf.Tensor.eval()是调用tf.get_default_session().run(t)的快捷方式。


我还会概述tf.Operation.run()方法,就像这里所示:

在会话中启动图形后,可以通过将操作传递给tf.Session.run()来执行操作。op.run()是调用tf.get_default_session().run(op)的快捷方式。


1

TensorFlow 2.x兼容回答: 将mrry的代码转换为TensorFlow 2.x(>= 2.0),以造福社区。

!pip install tensorflow==2.1
import tensorflow as tf

tf.compat.v1.disable_eager_execution()    

t = tf.constant(42.0)
sess = tf.compat.v1.Session()
with sess.as_default():   # or `with sess:` to close on exit
    assert sess is tf.compat.v1.get_default_session()
    assert t.eval() == sess.run(t)

#The most important difference is that you can use sess.run() to fetch the values of many tensors in the same step:

t = tf.constant(42.0)
u = tf.constant(37.0)
tu = tf.multiply(t, u)
ut = tf.multiply(u, t)
with sess.as_default():
   tu.eval()  # runs one step
   ut.eval()  # runs one step
   sess.run([tu, ut])  # evaluates both tensors in a single step

0
在TensorFlow中,您可以创建图形并将值传递给该图形。图形会根据您在图形中进行的配置执行所有的工作,并生成输出。 现在,当您向图形传递值时,首先需要创建一个TensorFlow会话。
tf.Session()

一旦会话初始化,您应该使用该会话,因为所有变量和设置现在都是会话的一部分。因此,有两种方法可以将外部值传递给图形,以便图形接受它们。一种方法是在使用正在执行的会话时调用 .run()。

另一种方式基本上是这个的快捷方式,即使用 .eval()。我说快捷方式,因为 .eval() 的完整形式是

tf.get_default_session().run(values)

你可以自己检查一下。 在 values.eval() 的位置上运行 tf.get_default_session().run(values)。你应该得到相同的结果。
eval 做的是使用默认会话,然后执行 run()。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接