Tensorflow backend - bug in model._make_predict_function(...)

问题

​ 最近在写qt界面做模型效果展示时,需要在另一个Qthread里进行深度学习模型的Inference。在单独的文件测试时没有问题。由于qt主线程进行耗时操作时会导致程序卡主崩溃,所以耗时工作需要放在Qthread线程中进行,可是当我在Qthread线程中直接进行模型的Inference,以期得到预测结果时,遇到了如下错误:

File "/home/angus/Envs/face/lib/python3.5/site-packages/keras/engine/training.py", line 1164, in predict
    self._make_predict_function()
  File "/home/angus/Envs/face/lib/python3.5/site-packages/keras/engine/training.py", line 554, in _make_predict_function
    **kwargs)
  File "/home/angus/Envs/face/lib/python3.5/site-packages/keras/backend/tensorflow_backend.py", line 2744, in function
    return Function(inputs, outputs, updates=updates, **kwargs)
  File "/home/angus/Envs/face/lib/python3.5/site-packages/keras/backend/tensorflow_backend.py", line 2546, in __init__
    with tf.control_dependencies(self.outputs):
  File "/home/angus/Envs/face/lib/python3.5/site-packages/tensorflow/python/framework/ops.py", line 5028, in control_dependencies
    return get_default_graph().control_dependencies(control_inputs)
  File "/home/angus/Envs/face/lib/python3.5/site-packages/tensorflow/python/framework/ops.py", line 4528, in control_dependencies
    c = self.as_graph_element(c)
  File "/home/angus/Envs/face/lib/python3.5/site-packages/tensorflow/python/framework/ops.py", line 3478, in as_graph_element
    return self._as_graph_element_locked(obj, allow_tensor, allow_operation)
  File "/home/angus/Envs/face/lib/python3.5/site-packages/tensorflow/python/framework/ops.py", line 3557, in _as_graph_element_locked
    raise ValueError("Tensor %s is not an element of this graph." % obj)
ValueError: Tensor Tensor("SR/BiasAdd:0", shape=(?, ?, ?, 3), dtype=float32) is not an element of this graph.

解决方案

解决方案在github Issue中找到了。

#Right after loading or constructing your model, save the TensorFlow graph:
graph = tf.get_default_graph()

#In the other thread (or perhaps in an asynchronous event handler), do:
global graph
with graph.as_default():
    (... do inference here ...)

这个解决方法相当有效,可能是keras将Tensorflow做backend在多线程模式中的一个Bug。后续版本可能会解决吧。