问题描述
事先训练好一个keras的神经网络model。在某一个网站项目flask中,启动服务的时候会把这个model加载进来,当用户访问某一个页面A的时候,会调用model的预测函数。线上一直没有问题,可是在某一次本地开发调试中,本地环境启动后,访问A页面,在调用model的预测函数时,出现如下的错误:
raise ValueError("Tensor %s is not an element of this graph." % obj)
ValueError: Tensor Tensor("dense_3/Sigmoid:0", shape=(?, 59), dtype=float32) is not an element of this graph.
调查过程
不通过服务,单独调用model的预测函数没有任何错误。
只要启动了服务,调用就会报错。
我尝试在service代码的构造函数中自动调用一次模型,然后再在A页面调用模型,就不会报错。
花了1个多小时研究这个问题。最后发现由于本地flask是开启debug模式的,因此服务启动的时候,debug模式又会来一个tensorflow的线程。这样导致服务调用tensorflow的时候,graph产生了错位。关闭flask的debug模式,问题消失。
经验总结
在调用keras的tensorflow的应用程序中,保证tensorflow的模型是单线程加载的。如果多线程加载模型的话,可能需要人为指定不同的Graph,具体还没有研究。