python - 如何使用 Flask 为 keras 模型提供推理服务?

标签 python flask keras deployment

我有一个yolo v3 keras模型的推理对象检测代码

#! /usr/bin/env python

import os
import argparse
import json
import cv2
from utils.utils import get_yolo_boxes, makedirs
from utils.bbox import draw_boxes
from keras.models import load_model
from tqdm import tqdm
import numpy as np
import flask
import io
from PIL import Image
from keras.preprocessing.image import img_to_array

config_path  = "config.json"
input_path   = "test.jpg"
output_path  = "output"

with open(config_path) as config_buffer:    
        config = json.load(config_buffer)

makedirs(output_path)

net_h, net_w = 416, 416 
obj_thresh, nms_thresh = 0.5, 0.45

os.environ['CUDA_VISIBLE_DEVICES'] = config['train']['gpus']
infer_model = load_model(config['train']['saved_weights_name'])


image = cv2.imread(input_path)

# predict the bounding boxes
boxes = get_yolo_boxes(infer_model, [image], net_h, net_w, config['model']['anchors'], obj_thresh, nms_thresh)[0]

# draw bounding boxes on the image using labels
_,outputs =  draw_boxes(image, boxes, config['model']['labels'], obj_thresh) 

print(outputs)

# write the image with bounding boxes to file
cv2.imwrite(output_path + input_path.split('/')[-1], np.uint8(image))

这工作得很好,在终端中给出了预期的输出类和坐标

{'classes': 'person 99.97%', 'X2': '389', 'X1': '174', 'Y1': '8', 'Y2': '8'}

但是当我通过使用官方 keras 转换将上述代码转换为 Flask 文档来将其转换为基于 REST api 的服务时,如下所示:

#! /usr/bin/env python

import os
import argparse
import json
import cv2
from utils.utils import get_yolo_boxes, makedirs
from utils.bbox import draw_boxes
from keras.models import load_model
from tqdm import tqdm
import numpy as np
import flask
import io
from PIL import Image
from keras.preprocessing.image import img_to_array


config_path  = "config.json"
input_path   = "test.jpg"
output_path  = "output"

with open(config_path) as config_buffer:    
        config = json.load(config_buffer)

makedirs(output_path)

net_h, net_w = 416, 416 
obj_thresh, nms_thresh = 0.5, 0.45

app = flask.Flask(__name__)

os.environ['CUDA_VISIBLE_DEVICES'] = config['train']['gpus']
infer_model = load_model(config['train']['saved_weights_name'])

def prepare_image(image_path):
    image = cv2.imread(image_path)
    return image

@app.route("/predict", methods=["POST"])
def predict():
    # initialize the data dictionary that will be returned from the
    # view
    data = {"success": False}

    # ensure an image was properly uploaded to our endpoint
    if flask.request.method == "POST":
        if flask.request.files.get("image"):
            # read the image in PIL format
            image = flask.request.files["image"].read()
            image = Image.open(io.BytesIO(image))

            # preprocess the image and prepare it for classification            
            image = img_to_array(image)


            boxes = get_yolo_boxes(infer_model, [image], net_h, net_w, config['model']['anchors'], obj_thresh, nms_thresh)[0]


            _,outputs =  draw_boxes(image, boxes, config['model']['labels'], obj_thresh)


            data.append(outputs)

            print(data)


            # indicate that the request was a success
            data["success"] = True

    # return the data dictionary as a JSON response
    return flask.jsonify(data)



if __name__ == "__main__":
    print(("* Loading Keras model and Flask starting server..."
        "please wait until server has fully started"))
    app.run()

enter image description here

在端口5000上成功运行

但是当我尝试使用

通过 POST api 进行预测时
curl -X POST -F <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8be2e6eaeceeb6cbffeef8ffa5e1fbec" rel="noreferrer noopener nofollow">[email protected]</a> 'http://localhost:5000/predict'

出现此错误

raise ValueError("Tensor %s is not an element of this graph." % obj) ValueError: Tensor Tensor("conv2d_59/BiasAdd:0", shape=(?, ?, ?,

255), dtype=float32) is not an element of this graph. 127.0.0.1 - - [15/Aug/2019 15:11:23] "POST /predict HTTP/1.1" 500 -

enter image description here

我不明白为什么相同的预测函数在没有 Flask 的情况下也能工作,但却出现错误。

最佳答案

我遇到了同样的问题,这是一个 keras 问题。主要似乎是在存在异步事件处理程序时触发 在加载经过训练的模型后立即添加 model._make_predict_function() 对我有用。 例如,

from keras.models import load_model
   model=load_model('yolo.h5')
   model._make_predict_function()

另一种对其他人有效的方法是使用图表并在上下文中进行推理,例如:

global graph
graph = tf.get_default_graph()
with graph.as_default():
res = model.predict()

欲了解更多见解,请参阅以下链接:

https://github.com/keras-team/keras/issues/6462

https://github.com/keras-team/keras/issues/2397

关于python - 如何使用 Flask 为 keras 模型提供推理服务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57512122/

相关文章:

python - 在 SQLAlchemy 中获取传感器的每种类型的最新读取值

python - Flask url_for 忽略端口

python - 在 Flask 应用程序中没有传入请求时连续打印一些内容

填充为 ='SAME' 的 Tensorflow/Keras Conv2D 层表现异常

python - 了解 Keras LSTM 中的字符级嵌入

python - Django Rest Framework POST 更新(如果存在或创建)

Python套接字.connect() "An invalid argument was supplied"(OSError : [WinError 10022])

python - 在 Python 中使用丢弃匹配迭代器

python - flask + 数据表 : how do you read the AJAX request that DataTables sends as JSON?

python - Keras ValueError : Shapes (32, 2) 和 (32, 4) 不兼容