我考虑的情景如下,在一个项目中,我有多个模型(用keras训练得到的),前一个模型的结果作为后面的多个模型的输入值。然后综合后面的多个模型的预测值整合成最终的项目的预测值。这个项目是用docker+gunicorn+flask来部署模型的,如果你不是部署模型,只是在自己的机器上运行,那么是不会出错的,但是当你把它们部署到服务器上时,却产生如下错误((只显示部分信息):
File "/home/user/anaconda3/lib/python3.7/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("output/BiasAdd:0", shape=(?, 2), dtype=float32) is not an element of this graph.
还有可能产生其他关于(Graph)的错误。
按照我的经验产生错误的原因是因为有多个模型,而我用的是基于tensorflow为后端的keras来训练模型的,所以在调用模型做预测时,各个模型的计算图(graph)以及会话(session) 搞乱了,因此需要显式的对各个模型建立各自的计算图以及会话。具体见下面的代码片段:
模型加载方法:
model_path = './models_trained/'
g1 = tf.Graph()
sess1 = tf.Session(graph=g1)
with sess1.as_default():
with g1.as_default():
group_1_model = load_model(model_path + 'group_1_model.h5')
g2 = tf.Graph()
sess2 = tf.Session(graph=g2)
with sess2.as_default():
with g2.as_default():
group_2_model = load_model(model_path + 'group_2_model.h5')
g3 = tf.Graph()
sess3 = tf.Session(graph=g3)
with sess3.as_default():
with g3.as_default():
group_3_model = load_model(model_path + 'group_3_model.h5')
模型调用方法:
if key in A:
with sess1.as_default():
with sess1.graph.as_default(): # 2
all_preds = group_1_model.predict(test_imgs)
elif key in B:
with sess2.as_default():
with sess2.graph.as_default(): # 2
all_preds = group_2_model.predict(test_imgs)
elif key in C:
with sess3.as_default():
with sess3.graph.as_default(): # 2
all_preds = group_3_model.predict(test_imgs)
这里需要强调的一点是,这错误只是在部署模型到服务器上时产生。而如果你在本地环境下是不用这么写的。但不知道为什么会产生这种差别。只能猜想docker下的环境还是和本地环境有所差别的,或许是在docker里少安装了某些软件包。