Python实战基于Flask部

风玲儿出处

掘金

本文主要记录在进行Flask部署过程中所使用的流程,遇到的问题以及相应的解决方案。

1、项目简介

该部分简要介绍一下前一段时间所做的工作:

基于深度学习实现一个简单的图像分类问题借助flask框架将其部署到web应用中并发要求较高

这是第一次进行深度学习模型的web应用部署,在整个过程中,进一步折射出以前知识面之窄,在不断的入坑、解坑中实现一版。

2、项目流程

这部分从项目实施的流程入手,记录所做的工作及用到的工具。

2.1图像分类模型1.模型的选择

需要进行图像分类,第一反应是利用较为成熟与经典的分类网络结构,如VGG系列(VGG16,VGG19),ResNet系列(如ResNet50),InceptionV3等。

考虑到是对未知类型的图像进行分类,且没有直接可用的训练数据,因此使用在Imagenet上训练好的预训练模型,基本满足要求。

如果对性能(耗时)要求较为严格,则建议使用深度较浅的网络结构,如VGG16,MobileNet等。

其中,MobileNet网络是为移动端和嵌入式端深度学习应用设计的网络,使得在cpu上也能达到理想的速度要求。是一种轻量级的深度网络结构。

MobileNet由Google团队提出,发表于CVPR-,论文标题:《MobileNets:EfficientConvolutionalNeuralNetworksforMobileVisionApplications》

2.框架选择

平时使用Keras框架比较多,Keras底层库使用Theano或Tensorflow,也称为Keras的后端。Keras是在Tensorflow基础上构建的高层API,比Tensorflow更容易上手。

上述提到的分类网络,在Keras中基本已经实现,Keras中已经实现的网络结构如下所示:

使用方便,直接导入即可,如下:

因此,选择Keras作为深度学习框架。

3.代码示例

以Keras框架,VGG16网络为例,进行图像分类。

fromkeras.modelsimportModelfromkeras.applications.vgg16importVGG16,preprocess_inputimportkeras.backend.tensorflow_backendasKTFimporttensorflowastfos.environ["CUDA_VISIBLE_DEVICES"]="0,1"#使用GPU#按需占用GPU显存gpu_options=tf.GPUOptions(allow_growth=True)sess=tf.Session(config=tf.ConfigProto(gpu_options=gpu_options))KTF.set_session(sess)#构建modelbase_model=VGG16(weights=‘imagenet’,include_top=True)model=Model(inputs=base_model.input,outputs=base_model.get_layer(layer).output)#获取指定层的输出值,layer为层名#进行预测img=load_image(img_name,target_size=(,))#加载图片并resize成x#图像预处理x=image.img_to_array(img)x=np.expand_dims(x,axis=0)x=preprocess_input(x)feature=model.predict(x)#提取特征2.2模型性能测试

将分类模型跑通后,我们需要测试他们的性能,如耗时、CPU占用率、内存占用以及GPU显存占用率等。

1.耗时

耗时是为了测试图像进行分类特征提取时所用的时间,包括图像预处理时间和模型预测时间的总和。

#使用python中的time模块importtimet0=time.time()....图像处理和特征提取....print(time.time()-t0)#耗时,以秒为单位

2.GPU显存占用

使用英伟达命令行nvidia-smi可以查看显存占用。

3.CPU,MEM占用

使用top命令或htop命令查看CPU占用率以及内存占用率。

内存占用还可以使用free命令来查看:

free-h:加上-h选项,输出结果较为友好,会给出合适单位

需要持续观察内存状况时,可以使用-s选项指定间隔的秒数:free-h-s3(每隔3秒更新一次,停止更新时按下Ctrl+c)

Ubuntu16.04版本中默认的free版本有bug,使用-s选项时会报错。

根据以上三个测试结果适时调整所采用的网络结构及显存占用选项。

命令具体含义可参考博文:

Linux查看CPU和内存使用情况[1]

2.3Redis使用

Redis=RemoteDIctionaryServer,是一个由SalvatoreSanfilippo写的高性能的key-value存储系统。Redis是一个开源的使用ANSIC语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日执行、key-value数据库,并提供多种语言的API。

Redis支持存储的类型有string,list,set,zset和hash,在处理大规模数据读写的场景下运用比较多。

1.基本使用

安装redis

pipinstallredis#测试importredis

基本介绍

redis.py提供了两个类:Redis,StrictRedis用于实现Redis的命令StrictRedis用于实现大部分官方命令,并使用官方的语法和命令Redis是StrictRedis的子类,用于向前兼容redis.py一般情况下我们就是用StrictRedis。

使用示例

#1.导入redisfromredisimportStrictRedis#2.连接数据库,指定host,端口号,数据库r=StrictRedis(host=‘localhost’,port=,db=2)#3.存储到redis中r.set(test1,value1)#单个数据存储r.set(test2,value2)#4.从redis中获取值r.get(test1)#5.批量操作r.mset(k1=v1,k2=v2)r.mset({k1:v1,k2:v2})r.mget(k1,k2)r.mget([k1,k2])2.Redis存储数组

Redis是不可以直接存储数组的,如果直接存储数组类型的数值,则获取后的数值类型发生变化,如下,存入numpy数组类型,获取后的类型是bytes类型。

importnumpyasnpfromredisimportStrictRedisr=StrictRedis(host=‘localhost’,port=,db=2)x1=np.array(([0.2,0.1,0.6],[10.2,4.2,0.9]))r.set(test1,x1)Truer.get(test1)b[[0.20.10.6]\n[10.24.20.9]]type(r.get(test1))#获取后的数据类型classbytes

为了保持数据存储前后类型一致,在存储数组之前将其序列化,获取数组的时候将其反序列化即可。

借助于python的pickle模块进行序列化操作。

importpickler.set(test2,pickle.dumps(x1))Truepickle.loads(r.get(test2))array([[0.2,0.1,0.6],[10.2,4.2,0.9]])

这样,就可以保持数据存入前和取出后的类型一致。

2.4web开发框架——Flask

之前学习python语言,从来没有

转载请注明:http://www.sonphie.com/jibzd/14561.html

  • 上一篇文章:
  • 下一篇文章: 没有了
  • 网站简介| 发布优势| 服务条款| 隐私保护| 广告合作| 网站地图| 版权申明

    当前时间: