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

Posted

技术标签:

【中文标题】在 TensorFlow 中,Session.run() 和 Tensor.eval() 有啥区别?【英文标题】:In TensorFlow, what is the difference between Session.run() and Tensor.eval()?在 TensorFlow 中,Session.run() 和 Tensor.eval() 有什么区别? 【发布时间】:2016-02-10 04:35:01 【问题描述】:

TensorFlow 有两种方法来评估图的一部分:Session.run 在变量列表上和Tensor.eval。这两者有区别吗?

【问题讨论】:

完整命名空间 tf.Tensor.eval()tf.Session.run(),但连接的是 tf.Operation.run()tf.Tensor.eval(),如 here 中所述 【参考方案1】:

如果你有一个Tensor 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

【讨论】:

第二个例子有什么不同?是否只是您可以评估单独的操作(或图表?不确定有什么区别)? 等等,你的例子真的运行了吗?我试过了:a = tf.constant(2.0) b = tf.constant(3.0) ab = tf.matmul(a, b),我刚收到来自 tensorflow 的抱怨说形状不匹配,我猜更准确地说,等级必须至少为 2。 @Pinocchio 我认为 API 发生了变化,因为原始答案是 4 年前发布的。我使用了tf.multiply(t, u),效果很好。【参考方案2】:

张量流的常见问题解答会话有一个answer to exactly the same question。我会继续把它留在这里:


如果tTensor 对象,则t.eval()sess.run(t) 的简写(其中sess 是当前默认会话。以下两个sn-ps 代码是等效的:

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() 可能更直接。

我建议您至少浏览整个常见问题解答,因为它可能会澄清很多事情。

【讨论】:

【参考方案3】:

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

如果我错了,请纠正我

【讨论】:

【参考方案4】:

在 tensorflow 中,您可以创建图表并将值传递给该图表。 Graph 会根据您在图中所做的配置完成所有工作并生成输出。 现在,当您将值传递给图表时,首先您需要创建一个 tensorflow 会话。

tf.Session()

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

其他基本上是捷径的方法是使用 .eval()。我说快捷方式是因为 .eval() 的完整形式是

tf.get_default_session().run(values)

您可以自己检查。 在values.eval() 的地方运行tf.get_default_session().run(values)。你必须得到同样的行为。

eval 所做的是使用默认会话,然后执行 run()。

【讨论】:

【参考方案5】:

要记住的最重要的事情:

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

知道这一切都是easy:

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


我还将概述tf.Operation.run() 中的方法here:

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

【讨论】:

【参考方案6】:

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

【讨论】:

以上是关于在 TensorFlow 中,Session.run() 和 Tensor.eval() 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 tensorflow 2.5 中运行 tensorflow 分析

TensorFlow Hub 模块可以在 TensorFlow 2.0 中使用吗?

显式 tensorflow 会话在 Tensorflow/nmt 中给出获取错误

tensorflow环境下安装Python包

tensorflow 传入值-老鱼学tensorflow

Tensorflow 2.2.0-rc4 AttributeError:模块'tensorflow.compat.v1'在Spyder中没有属性'contrib'?