因为本人刚从源头接触TensorFlow,所以会有许多各位大佬看起来是常识的东西不太懂,而这种认知差有时候比问题本身还让人难受。我想各位刚接触的同学跟我一定也有相同感受,所以我想用一个初学者的视角尝试说明问题。
本次更新我将对这一问题彻底说明。
在熟悉TensorFlow的时候,我写了一段简单的代码,但运行的时候却报错RuntimeError: The Session graph is empty. Add operations to the graph before calling run().
import tensorflow as tf
a = tf.constant(1.0)
b = tf.constant(1.0)
op1 = tf.add(a, b)
with tf.compat.v1.Session() as sess:
m = sess.run(op1)
print m
代码是没问题的,搜了网上的解决方法都没有用。我在想了一会儿之后,觉得可能是graph的问题,于是运行
a is tf.compat.v1.get_default_graph()
结果果然是False,说明上面的几个op并没有添加到默认的graph中去。于是我找到了解决方法。
import tensorflow as tf
g = tf.Graph()
with g.as_default():
a = tf.constant(1.0)
b = tf.constant(1.0)
op1 = tf.add(a, b)
with tf.compat.v1.Session(graph=g) as sess:
m = sess.run(msg)
print m
成功解决。
问题说明:
这一问题出现的根本原因在于我入手的TensorFlow版本是2.0,从我代码中的tf.Session()被我写成了tf.compat.v1.Session()就可以看出。
TensorFlow1.x版本用的是Graph Execution,可以称为静态的图机制。所以我们的处理主要分成两个部分:
1.在一个graph上添加节点和连线,也就是构建我们要用的模型。我们将graph理解为一张空白的设计图,而我们在这张纸上画圈画线。
2.在tf.Session()中运行我们的在某一graph上运行的model。可以理解为运用我们画好的设计图纸,创建出一个机器,实现我们需求的功能。因为只有图纸是做不了事情的。
由于TensorFlow1.x的这一机制,所以我们在刚开始写程序的时候就是有默认的graph的,也就是有默认的图纸的。我们所创建的各个节点都在这个默认的graph上。所以TensorFlow1.x是不会遇到这一问题的。
但TensorFlow2.0用的是Eager Execution,称为动态图机制。关于这一机制我理解还不深,先不做说明。所以在TensorFlow2.0中,上述中的默认的图纸还在,我们还是可以通过tf.compat.v1.get_default_graph()来获得它,但是我们创建的节点并没有默认保存在它的上面。而当我们调用tf.Session()时,默认拿的就是这一默认graph来实现模型,但我们写的东西又不在默认的graph上,graph是一片空白,于是就会报这个错。
所以如果我们还要用TensorFlow1.x的静态图方法,我们就要自己创建一个graph,并在调用session的时候声明调用我们绘制的graph,就可以运行了。
因为TensorFlow2.0与1.x有很多不同,如果同学们只想要学1.x的写法应该怎么办呢。我们只需要在开头添加这样两句代码。
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()
第一句的意思是将tf.compat.v1简化成tf,这样我们就可以像1.x一样调用tf.Session()等,而不用那么麻烦。第二句话是使TensorFlow2.0的功能无效化,这样就跟1.x一样了。
如果觉得有帮助的话,可以点个赞再走吗。
当然大家如果还有什么问题,可以评论留言,我会和大家一起讨论。