3

我有几个不同文件的文件:

  • 主文件
  • 观看.py
  • 读取.py
  • detect.py <-- 使用 darkflow依赖于图形模式的基于 tensorflow 的库
  • translate.py <-- 使用 tf 急切执行

在暗流的 TFNet 初始化期间,我收到此错误:

Traceback (most recent call last):
  File "/home/justin/Projects/comp3931/main.py", line 6, in <module>
    watcher = 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对暗流类的调用不兼容TFNetDectectordetect.py

如果我translate.py独立于其他人运行它可以正常工作,如果其他模块在不translate.py涉及的情况下运行它们也可以正常工作。

我猜他们使用不同的上下文(图形/渴望),整个事情不能在同一个程序中一起运行。我试过查看文档,但找不到在需要时切换回图形模式的方法。

有什么方法可以在不同地方的同一个应用程序中同时运行渴望和图形模式?

4

2 回答 2

14

最好编写与图形模式和急切执行兼容的代码。从文档中:

  • 使用 tf.data 代替队列进行输入处理。它更快更容易。
  • 使用面向对象的层 API——比如 tf.keras.layers 和 tf.keras.Model——因为它们有明确的变量存储。
  • 大多数模型代码在 Eager 和图形执行期间的工作方式相同,但也有例外。(例如,动态模型使用 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_modegraph_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())

这确实是一种 hack,但如果您不喜欢将所有代码嵌套在with块中,它可能在 Jupyter 笔记本中很有用。

于 2018-05-11T17:53:40.310 回答
-2

https://www.tensorflow.org/programmers_guide/eager (向下滚动到“在图形环境中使用急切执行”)。

也许这有帮助...

于 2018-04-11T12:28:10.553 回答