将一个巨大的Keras模型加载到Flask应用程序中

3

我正在构建一个小型的Flask应用程序,它在后台使用卷积神经网络对用户上传的图像进行预测。如果我像这样加载它,它就可以正常工作:

@app.route("/uploader", methods=["GET","POST"])
def get_image():
    if request.method == 'POST':
        f = request.files['file']
        sfname = 'static/'+str(secure_filename(f.filename))
        f.save(sfname)
        clf = catdog.classifier()
        return render_template('result.html', pred = clf.predict(sfname), imgpath = sfname)

然而,这需要在用户添加图像后加载分类器(clf)。这需要一段时间,因为它需要从pickle文件中设置200多个层神经网络的所有权重。

我想要做的是在应用程序生成时加载所有权重。为此,我尝试了以下方法(剔除HTML模板/导入/应用程序启动的不相关代码):

# put model into memory on spawn
clf = catdog.classifier()
# Initialize the app
app = flask.Flask(__name__)

@app.route("/uploader", methods=["GET","POST"])
def get_image():
    if request.method == 'POST':
        f = request.files['file']
        sfname = 'static/'+str(secure_filename(f.filename))
        f.save(sfname)
        return render_template('result.html', pred = clf.predict(sfname), imgpath = sfname)

当我执行此操作时,我会得到以下回溯信息(跳过顶部所有特定于 Flask 的跟踪信息):
 File "/Users/zachariahmiller/Documents/Metis/test_area/flask_catdog/flask_backend.py", line 26, in get_image
    return render_template('result.html', pred = clf.predict(sfname), imgpath = sfname)
  File "/Users/zachariahmiller/Documents/Metis/test_area/flask_catdog/catdog.py", line 56, in predict
    prediction = self.model.predict(img_to_predict, batch_size=1, verbose=1)
  File "/Users/zachariahmiller/anaconda/lib/python2.7/site-packages/keras/engine/training.py", line 1569, in predict
    self._make_predict_function()
  File "/Users/zachariahmiller/anaconda/lib/python2.7/site-packages/keras/engine/training.py", line 1037, in _make_predict_function
    **kwargs)
  File "/Users/zachariahmiller/anaconda/lib/python2.7/site-packages/keras/backend/tensorflow_backend.py", line 2095, in function
    return Function(inputs, outputs, updates=updates)
  File "/Users/zachariahmiller/anaconda/lib/python2.7/site-packages/keras/backend/tensorflow_backend.py", line 2049, in __init__
    with tf.control_dependencies(self.outputs):
  File "/Users/zachariahmiller/anaconda/lib/python2.7/site-packages/tensorflow/python/framework/ops.py", line 3583, in control_dependencies
    return get_default_graph().control_dependencies(control_inputs)
  File "/Users/zachariahmiller/anaconda/lib/python2.7/site-packages/tensorflow/python/framework/ops.py", line 3314, in control_dependencies
    c = self.as_graph_element(c)
  File "/Users/zachariahmiller/anaconda/lib/python2.7/site-packages/tensorflow/python/framework/ops.py", line 2405, in as_graph_element
    return self._as_graph_element_locked(obj, allow_tensor, allow_operation)
  File "/Users/zachariahmiller/anaconda/lib/python2.7/site-packages/tensorflow/python/framework/ops.py", line 2484, in _as_graph_element_locked
    raise ValueError("Tensor %s is not an element of this graph." % obj)
ValueError: Tensor Tensor("dense_2/Softmax:0", shape=(?, 2), dtype=float32) is not an element of this graph.

我不确定为什么将分类器作为全局对象加载到应用程序之外会导致它失败。它应该在内存中,我已经看到其他人使用SKLearn分类器进行这样的操作的示例。有关此问题的任何想法?


看起来像是线程问题。谷歌搜索显示在使用Keras和Tensorflow以及Flask时出现了几个类似的问题。其中一个解决方案似乎是明确地在正确的图上工作:https://www.tensorflow.org/versions/r0.11/api_docs/python/framework/utility_functions#get_default_graph - Martin Krämer
2个回答

5

1
我不得不执行 app.run(debug=False, threaded=False)。大多数情况下,我喜欢Python,但有时错误消息没有帮助。 - Paul Williams

3

你好,我曾经遇到过相同的问题。

我在运行Python服务器时使用了threaded=True参数。将其移除后,问题得以解决。

app.run(host='0.0.0.0', port=5000, threaded=True)

---->

app.run(host='0.0.0.0', port=5000)

对我来说,调试似乎没有影响任何东西。


1
谢谢提供的信息。我卡在这里了,在我的情况下,我必须明确地定义threaded = False。 - Abhishek Tripathi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接