我有几个文件与不同的文件:
main.py
watch.py
read.py
detect.py < - 使用darkflow
依赖于图模式的基于张量流的库
translate.py < - 使用tf eager执行
在darkflow的TFNet初始化期间,我收到此错误:
Traceback (most recent call last): File "/home/justin/Projects/comp3931/main.py", line 6, inwatcher = Watcher('res/vid/planet_earth_s01e01/video.mp4', 'res/vid/planet_earth_s01e01/english.srt') File "/home/justin/Projects/comp3931/watch.py", line 9, in __init__ self.detector = Detector() File "/home/justin/Projects/comp3931/detect.py", line 6, in __init__ self.tfnet = TFNet(self.options) File "/usr/local/lib64/python3.6/site-packages/darkflow/net/build.py", line 75, in __init__ self.build_forward() File "/usr/local/lib64/python3.6/site-packages/darkflow/net/build.py", line 105, in build_forward self.inp = tf.placeholder(tf.float32, inp_size, 'input') File "/usr/local/lib/python3.6/site-packages/tensorflow/python/ops/array_ops.py", line 1677, in placeholder raise RuntimeError("tf.placeholder() is not compatible with " RuntimeError: tf.placeholder() is not compatible with eager execution.
所以,我认为,当我实例Translator
从类translate.py
文件时,它调用了整个计划,然后是不是要darkflow的电话兼容急于执行TFNet
中使用类Dectector
从类detect.py
如果我translate.py
独立于其他人运行它工作正常,其他模块如果运行它们没有translate.py
参与也可以正常工作.
我猜他们使用不同的上下文(graph/eager)这一事实,整个事情不能在同一个程序中一起运行.我已经尝试查看文档,但在需要时找不到切换回图形模式的方法.
有什么方法可以在不同的地方在同一个应用程序中运行eager和graph模式吗?
最好编写兼容图形模式和急切执行的代码.从文档:
使用tf.data进行输入处理而不是队列.它更快更容易.
使用面向对象的层API(如tf.keras.layers和tf.keras.Model),因为它们具有显式的变量存储.
在热切和图形执行期间,大多数模型代码的工作方式相同,但也有例外.(例如,使用Python控制流的动态模型根据输入更改计算.)
一旦使用tf.enable_eager_execution启用了急切执行,就无法关闭它.启动一个新的Python会话以返回图形执行.
也就是说,通过使用,可以在图形模式下使用急切执行tfe.py_func()
.这是文档中的代码示例(我刚刚添加了导入和断言):
import tensorflow as tf import tensorflow.contrib.eager as tfe def my_py_func(x): assert tf.executing_eagerly() x = tf.matmul(x, x) # You can use tf ops print(x) # but it's eager! return x assert not tf.executing_eagerly() with tf.Session() as sess: x = tf.placeholder(dtype=tf.float32) # Call eager function in graph! pf = tfe.py_func(my_py_func, [x], tf.float32) sess.run(pf, feed_dict={x: [[2.0]]}) # [[4.0]]
反过来也是可能的,正如Alex Passos在本视频中所解释的那样.以下是受视频启发的示例:
import tensorflow as tf import tensorflow.contrib.eager as tfe tf.enable_eager_execution() def my_graph_func(x): assert not tf.executing_eagerly() w = tfe.Variable(2.0) b = tfe.Variable(4.0) return x * w + b assert tf.executing_eagerly() g = tfe.make_template("g", my_graph_func, create_graph_function_=True) print(g(3))
还有一种非官方的方式来切换模式,使用如下定义的eager_mode
和graph_mode
上下文tensorflow.python.eager.context
:
import tensorflow as tf import tensorflow.contrib.eager as tfe from tensorflow.python.eager.context import eager_mode, graph_mode with eager_mode(): print("Eager mode") assert tf.executing_eagerly() x1 = tfe.Variable(5.0) print(x1.numpy()) print() with graph_mode(): print("Graph mode") assert not tf.executing_eagerly() x2 = tfe.Variable(5.0) with tf.Session(): x2.initializer.run() print(x2.eval())
因为它不是官方的,你应该在生产代码中避免它,但它可能在调试时或在Jupyter笔记本中派上用场.最后一个选项是使用此switch_to()
功能:
import tensorflow as tf import tensorflow.contrib.eager as tfe from tensorflow.python.eager.context import context, EAGER_MODE, GRAPH_MODE def switch_to(mode): ctx = context()._eager_context ctx.mode = mode ctx.is_eager = mode == EAGER_MODE switch_to(EAGER_MODE) assert tf.executing_eagerly() v = tfe.Variable(3.0) print(v.numpy()) assert tf.get_default_graph().get_operations() == [] switch_to(GRAPH_MODE) assert not tf.executing_eagerly() v = tfe.Variable(3.0) init = tf.global_variables_initializer() assert len(tf.get_default_graph().get_operations()) > 0 with tf.Session(): init.run() print(v.eval())
这真的是一个黑客,但它可能在Jupyter笔记本中很有用,如果你不喜欢将所有代码嵌套在with
块中.