我有一个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()
在端口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 -
我不明白为什么相同的预测函数在没有 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()
欲了解更多见解,请参阅以下链接:
关于python - 如何使用 Flask 为 keras 模型提供推理服务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57512122/