Task
- 理解
Keras+TF
项目部署 - 使用
Keras+TF
在Falsk
中部署 Flask
使用进阶Flask
托管和部署
Reference
- global示例
- python中的模块、库、包有什么区别?
- python的构建工具setup.py
- Python项目中的Makefiles
- Cython的用法以及填坑姿势
- pyx文件 生成pyd 文件用于 cython调用
- Python深入:Distutils发布Python模块
- Python程序执行顺序
- Keras + Flask 提供接口服务的坑~~~
- keras+tornado多次加载model时的bug
Start
一份程序为了区分主动执行还是被调用,Python引入了变量
__name__
,当文件是被调用时,__name__
的值为模块名,当文件被执行时,__name__
为__main__
如果使用
from A import B
,其实等于import A
,b=A.b
·。其中A
内非函数代码也会执行介绍
globe
。首先看一个变量作用域的错误示例1
2
3
4
5
6n=0
def func():
print n
n+=1
func()报错:
UnboundLocalError: local variable 'xxx' referenced before assignment
,即函数内部不能修改局域变量,使用globe
1
2
3
4
5
6
7
8n=0
def func():
global n
print n
n+=1
func()
print n这时,n就成为了全局变量,在函数内部修改该变量,也就没有问题了。
通常定义:
Lib
为依赖库;Bin
类似通常定义默认程序集缓存
,可理解为优先级高代码目录Cython: 将Python代码( .py .pyx )翻译为C( .c )代码,去掉指令解释这个阶段,直接进入C代码层,效率就比较高了.
1
2
3
4
5
6
7
8
9
10
11Cython一般出现于“python setup.py build_ext --inplace”
其中“setup.py”内大致出现如下:
===========================
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules = cythonize("test.py"))
========================================
#test.c是test.py转化后的C代码文件,test.c非常大
#test.pyd是python的动态链接库,我们在使用import test时会加载, 若是Liuix则是(.so)文件而不是(.pyd)
#build目录编译过程中生成的临时文件Makefile:通常情况下,它们用于编写C程序,来减轻代码可以作为程序使用前所需要做的所有东西。在Python项目中使用makefile,其实说白了就是一个shell脚本。放在makefile中的一个规则下,使其他人很容易地运行对项目的测试。示例见此
模块
module
,库lib
,包package
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15module:一个 .py 文件就是个 modulelib:抽象概念,和另外两个不是一类,只要你喜欢,什么都是
以下放上详细的:
============================================================
模块(module):Python中可复用的基本代码单元,可由其他代码import的一块代码,这里我们只关
注三种类型的模块:纯python模块,扩展模块和包。
纯python模块(pure Python module): 由python编写的模块,包含在单独的py文件中(或者是pyc/pyo文件)。
扩展模块(extension module):由实现Python的底层语言编写的模块(C/C++ for Python, Java for Jython)。通常包含在单独的动态加载文件中,比如Unix中的so文件,windows中的DLL文件,或者是Jython扩展的java类文件。(注意,目前为止Distutils只能处理Python的C/C++扩展)
=============================================================
lib,就算只有个 hello world,通常称依赖库
package:就是个带 __init__.py 的文件夹,并不在乎里面有什么,不过一般来讲会包含一些 packages/modules
scrapy、flask、Django、numpy、scipy、NLTK、jieba 在你的语境下,一般都被认为是 lib,因为关注点不是他们的代码是怎么组织的。
简单讲,Package是由很多module组成,来实现某种功能,modules由函数和类组成。库是抽象概念,也可以是各种模块组成。setup.py
本地安装包。不安装可以直接运行包源码吗?答案是可以,不过得首先编译Cython
代码,即执行python setup.py build_ext --inplace
。详细setup.py
解析见此举两个具体例子,串起之前知识点,并说明
setup.py
的工作:①Keras+TF
在某个
Keras+TF
项目里,模型的TF
部分的实现部分通过调用其内Lib
实现,目录如下:但直接
form lib import xxx
可能会报错,那为什么要执行make.sh
呢?查看
mask.sh
源码:
编译pyx文件——Lib库内模型需要;提速;
若不执行则报错:
ImportError: cannot import name 'bbox'
,对应Github
的Issue
(哈哈哈哈哈哈哈哈哈。。。不过这里还真有老哥搞定了)
执行
python setup.py build_ext --inplace
移动文件
删除文件
好了,进入
setup.py
:配置CUDA
Distutils发布Python模块——扩展模块
Extension
是纯Python的扩展模块,构造Extension
指定扩展名、源码文件以及其他编译/链接需要的参数(需要包含的目录,需要连接的库等等)。其中第二个参数为指定的源码文件。nms
(非极大值抑制)和bbox
(Bounding box)都是物体侦测相关的,属于faster-rcnn
,具体可见此执行setup
ext_modules
是Extension实例
的列表,每一个Extension实例
描述了一个独立的扩展模块。这里可理解为部署faster-rcnn
。到此,整个mask.sh
执行完毕,用户可方便使用项目代码。②Keras
在某个
Keras
项目里,作者代码没传Pypi,而是提供了包的形式供安装。安装即cd进目录
pip install .
或者python setup.py
查看
setup.py
:比较规范的写法~规范可见此
其中:
cmdclass
: 添加自定义命令,我的理解就是解析命令行的初始化媒介。这里传入是构造类;找的一个扩展entry_points
: entry_points中: console_scripts* 指明了命令行工具的名称;在retinanet-train=keras_retinanet.bin.train:main
中,等号前面指明了工具包的名称,等号后面的内容指明了程序的入口地址
With Flask
在start部分学习了解了Keras+TF项目的安装部署,方便出错解决。接下来让我们来学习在Flask中如何部署Keras+TF。
tensorflow程序一般分为两个阶段:
1 | 1、定义计算图所有的计算 |
在tensorflow程序中,系统会自动维护一个默认的计算图,可以通过tf.get_default_graph()
函数获取。
然后我们进入Flask中去。
####
因为重复生成session浪费时间和资源。如何使Keras+TF
的计算图在Flask中不变呢?那就是不写进函数,提前实例化出来~每次再把session和模型喂入识别函数~
注:代码中是TF模型结果传给Keras。我的理解是Keras一个计算图,TF一个计算图。
在Tensorflow
中:
在Keras
中:
####
可以这么理解:张量Tensor
的计算图要和session
中的计算图相同。当前session里的图和模型中的图的各种参数不匹配就报错,所以得定义了一个全局的图,每次都用这个图。
Flask
自身存在Bug,不详细展开,这里写一下解决方案。
- 保证TF模型单线程
在调用keras的tensorflow的应用程序中,保证tensorflow的模型是单线程加载的。如果多线程加载模型的话,可能需要人为指定不同的Graph,具体还没有研究。
保证方法:①实例化加载;②Flask
的app.run()
内设置debug
为False
,因为debug
开启了Tensorflow
线程,使Tensorflow
线程从单变多
session
中还有其他模型数据这个错也可以说叫,当前
session
里的图和模型中的图的各种参数不匹配,这是Keras
的自身Bug
。首先,在Keras预测模块,可以这么写:
即,使用globe导入实例化后的
Keras
模型,然后函数内with _GRAPH_MA.as_default():
内进行预测,其中_GRAPH
是函数外实例化的Graph
然后,在
app.py
主函数__main__
内,在app.run()
之前,预先跑一遍模型,导通Session
和Graph
题外话
Keras
训练时:然后
K.set_session(get_session())
即可。Tensorflow
训练时:然后 加载预训练时
1
2
3
4
5
6
7
8
9saver = tf.train.Saver()
try:
ckpt = tf.train.get_checkpoint_state(cfg.TEST.checkpoints_path)
print('Restoring from {}...'.format(ckpt.model_checkpoint_path), end=' ')
saver.restore(sess, ckpt.model_checkpoint_path)
print('done')
except:
raise 'Check your pretrained {:s}'.format(ckpt.model_checkpoint_path)
**训练**时`sess.run(...)`即可。
TODO
- Other Ticks
- Tf.Config
- tf.GPUOptions
- realse Flask
- 托管
- 部署
- 【Flask】 Not Found: /favicon.ico 项目logo图标加载
Flask
接收Xmlhttprequset
- Flask动态静态请求及进阶以及
js/zxxFile.js
- 开发技巧·TensorFlow&Keras GPU使用技巧
————Edit By Kevin