解决了下 flask+imageai 的集成问题。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
xiaolinjia
V2EX    Python

解决了下 flask+imageai 的集成问题。

  •  
  •   xiaolinjia 2019-08-08 14:57:32 +08:00 2326 次点击
    这是一个创建于 2255 天前的主题,其中的信息可能已经有所发展或是发生改变。

    www.v2ex.com/t/588188#reply0 那天发了上面这个,各位见笑了。主要是我那天想,就一个全局变量这么简单的问题,居然还报错,花了我一整天。 不过最终还是解决了,那下面给出解决方案供大家参考吧。

    场景是,我想用 flask+imageai 来分析处理一张图片。

    一开始把 imageai 的加载 model 和处理都放在一个函数里了,然后别人访问这个 url,就调用分析处理函数,处理这图片(这一步是没有出现问题的)。

    然后发现了一个缺点是每次都要 loadModel 一次,效率大打折扣。既然每次都用的同一个训练模型(目前 imageai 的图像识别只提供了两种模型),没必要每次访问 url 都 load 一次模型吧。

    之后理所当然得将初始化( loadModel 之类)的步骤都放全局里,想着就是刚启动服务器就直接加载模型,之后访问 url 就直接执行分析操作就好。

    结果发现迷之报错,加上我本身也不做机器学习这块,还不懂报错的原因是什么。。。去 imageai 的 issue 里看 OlafenwaMoses/ImageAI/issues/159 说是设置成 global 可以防止多次加载 model 就行了,但是也没解决。

    没法,只好从根源错误找起。 根源好像是 tensorflow 模块(毕竟 imageai 也依赖了这个库)报的错,ValueError: Tensor Tensor("keras_learning_phase:0", shape=(), dtype=bool) is not an element of this graph. 然后又去 Stack Overflow 里搜了一堆 TensorFlow 的问题,说起来也没怎么懂,不过大概看出来以上错误有不少情况都是因为在 tensorflow 中用了多线程 /多进程导致的。 既然如此,突然想起,那就把 flask 的多线程、多进程禁用了吧。 结果,居然成了。反正就公司内部里用用,不用多线程就不用吧,也没啥。

    下面的是我的成功了的代码。

    from flask import Flask, Response, jsonify app = Flask(__name__) import os from imageai.Detection import ObjectDetection import time import json execution_path = os.getcwd() st = time.time() detector = ObjectDetection() detector.setModelTypeAsRetinaNet() detector.setModelPath(os.path.join(execution_path, "model", "resnet50_coco_best_v2.0.1.h5")) # detector.setModelTypeAsTinyYOLOv3() # detector.setModelPath(os.path.join(execution_path, "model", "yolo-tiny.h5")) detector.loadModel() # detector.loadModel(detection_speed="fastest") print(f'Init Timer: {time.time()-st}') @app.route('/detect/<pic_name>') def boat_detection(pic_name): st = time.time() results = getDetections(pic_name) print(f'Sum Timer: {time.time()-st}') msg = {} for i, result in enumerate(results, 1): result['percentage_probability'] = float(result['percentage_probability']) result['box_points'] = list(result['box_points']) for index in range(len(result['box_points'])): result['box_points'][index] = int(result['box_points'][index]) result['box_points'] = tuple(result['box_points']) msg[str(i)] = json.dumps(result) return jsonify(msg) def getDetections(file_name): start = time.time() image_folder = os.path.join(execution_path, 'data\\ship2\\') output_folder = os.path.join(execution_path, 'data\\output\\') st1 = time.time() image_file = os.path.join(image_folder, file_name) new_image_file = os.path.join(output_folder, file_name) print(image_file, "-->", new_image_file) if not os.path.exists(image_file): print("not exist.") return # global detector custom_objects = detector.CustomObjects(boat=True) detectiOns= detector.detectCustomObjectsFromImage( custom_objects=custom_objects, input_image=image_file, output_image_path=new_image_file, minimum_percentage_probability=30) print(f'[Info]识别到 boat{len(detections)}艘') for eachObject in detections: print(eachObject.items()) end = time.time() print(f'Excute Timer: {end-st1}') print ("耗时: ",end-start) return detections if __name__ == '__main__': app.run(threaded=False) 

    重点就是在 app.run()里设置成禁用多线程、多进程,global 有没有都无所谓。毕竟没涉及到修改 detector。

    1 条回复    2019-12-20 11:59:56 +08:00
    xiaolinjia
        1
    xiaolinjia  
    OP
       2019-12-20 11:59:56 +08:00
    最近又学习了一些机器识别的问题,发现 keras 有个 session.graph 存放了这个 model,而 imageai 有一个参数可以设置用 session.graph。也就是多线程共用一个 model。
    因此,如果 flask 开启多线程也没事。只需要在该方法里添加个参数 thread_safe=True 即可,如下:
    detectiOns= detector.detectCustomObjectsFromImage(
    custom_objects=custom_objects,
    input_image=image_file,
    output_image_path=new_image_file,
    minimum_percentage_probability=30,
    thread_safe=True,
    )
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2772 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 14:45 PVG 22:45 LAX 07:45 JFK 10:45
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86