深度学习图像分类开源项目(1) - 使用flask部署VGG16神经网络算法模型

该完整项目由团队协作完成,已上传至GitHub,点击直达
gdit-ai

团队信息

广东科学技术职业学院 计算机工程技术学院(人工智能学院)AI应用实验室
主要从事深度学习算法、计算机视觉、智能算法应用与部署,基于人工智能,计算机视觉算法web前后端应用开发,android开发,微信小程序开发,可以承接相关的项目开发业务。QQ群:971601256
指导老师:胡建华,余君

环境配置

系统环境:Ubuntu16.04 LTS、python3.x、Anaconda3和相关的编辑器
所需python库:numpy、tensorflow、Keras、opencv、Flask及相关依赖

必备知识

编辑器:Pycharm和HBuilder X
后端:python3.x、Flask
前端:前端三大件(html+css+javascript)Vue、Element、axios

项目结构

深度学习图像分类开源项目(1) - 使用flask部署VGG16神经网络算法模型_第1张图片
|——static #静态资源目录,此处为存放前端上传的图片
|——lib #css、js文件存放目录
|——upload #图片上传后的保存目录
|——index.html #前端页面代码
|——mange.py #Flask启动文件(主文件)
|——package.txt #记录运行此项目所需要的依赖包及版本信息(使用pip freeze>package.txt)命令打包
|——PredictAndMove.py #封装后的模型预测文件
|——vggmodel_65-0.00-1.00.hdf5 #hdf5模型文件

Flask非常灵活,官方并没有给出一个固定的项目目录组织结构,此处的目录结构仅为个人习惯以及项目调用使用,也更加符合大型项目结构的工程化构建方法。

算法模型保存

保存Keras模型有很多种方法,首先不推荐使用pickle或cPickle来保存Keras模型,此处使用model.save()函数将Keras模型和权重保存在一个HDF5文件中。
HDF5模型保存结构

  • 模型的结构,刹车改造该模型
  • 模型的权重
  • 训练配置(损失函数,优化器等)
  • 优化器的状态,煞于从上次训练中断的地方开始

前端页面

该项目采用前后端分离的组织架构,使用最流行的前端Vue框架以及Element组件库,使用axios通过JSON数据进行前后端的交互。

<div id="app">
			input>
			<el-button type="primary" round @click="handleClick" v-if="upload_awesome">上传图片el-button>
			<div v-for="(file,index) in imageData">
				<el-tag type="success" style="margin:5px 5px;display: flex;justify-content:center;">识别结果为:{{index}}el-tag>
				<el-row>
					<el-col :span="6" v-for="img in file">
						<div class="img-box" style="width: 100%;">
							<img :src="img.path" alt="图片正在加载...">

						div>
					el-col>
				el-row>
			div>
		div>

为保证项目可以正常运行,建议参照官方文档下载和安装完整的Vue、Element、和axios包文件。这里为了压缩项目文件大小,所以只引入了用到的文件,并不是很好的做法。
官方文档地址
Vue: https://cn.vuejs.org/v2/guide/
Element: https://element.eleme.cn/#/zh-CN/component/installation
Axios: http://www.axios-js.com/zh-cn/docs/#axios

1:必须HTML头部(head)使用link标签引入element的css样式文件,script标签分别引入vue.min.js、element.js、axios.min.js文件。
2:页面主体使用element的el-button组件编写上传图片按钮,el-tag组件渲染模型的识别结果,el-col和el-row组件控制图片显示的布局风格。
3:使用@符号绑定了事件函数,用来在JavaScript中调用这些函数进行逻辑处理。

<script type="text/javascript">
		var vm = new Vue({
			el: '#app', // 创建Vue实例
			data: { //定义数据对象
				upload_awesome: true,
				imageData: {},
				file: '',
				retData: '',
                index:'识别中'
			},
			methods: { //事件处理器,this将自动绑定到Vue实例上面
				handleClick() {
					this.$refs['input'].click();
				},
				fileChange(e) {
					this.file = e.target.files[0];
					this.uploads()
				},
				uploads() {
					let self = this;
					let param = new FormData();
					param.append('file', this.file);
					axios.post('/upload/', param, {}).then(function(response) {
							if (response.status === 200) {
								let data = response.data;
								self.$set(self.$data, 'imageData', data)
								self.$set(self.$data, 'upload_awesome', false)
							}
						})
						.catch(function(error) {
							console.log("上传图片失败!")
						})
				},
			}
		})
	</script>

这里编写前端逻辑代码,包括上传和展示,下面分别介绍自定义的三个函数fileChange()、handleClick()和uploads()。

handleClick()

该函数主要是点击上传按钮之后,动态的去改变input属性,从而触发

fileChange()

使用@change对input的值进行监听,如果监听到值的改变,就截取上传文件的name,并调用upload()函数

uploads()

该函数为主函数,即是通过该函数与服务器通信,以获取、交换数据。下面对该函数的核心代码进行解读

param.append('file', this.file);

将上传的文件信息加入到param变量

axios.post()

axios中post请求实例方法的别名,创建该请求的基本配置选项如下axios.post(url[, data[, config]]),即请求路径(url)、数据、和配置,只有URL是必需的,详情请访问下面网址http://www.axios-js.com/zh-cn/docs/#axios-options-url-config-1
then函数则接受该请求的响应信息,结构如下:
深度学习图像分类开源项目(1) - 使用flask部署VGG16神经网络算法模型_第2张图片
通过if (response.status === 200) {}
判断响应状态,并更新相应的数据,同时视图会进行重渲染,这是vue的特性。
在使用catch时,或传递拒绝回调作为then的第二个参数时,响应可以通过error对象可被使用,主要作用是处理错误。

服务器端(flask后端)

项目涉及到flask的内容较少,考虑到实用性的问题,此处并没有对核心代码进行路由、蓝图规划和拆分(后面可能会进行更新)。

import os
import json
from flask import Flask, request, jsonify
from werkzeug.utils import secure_filename

导入python的第三方库文件,以及flask用到的依赖库文件

@app.route('/upload/', methods=['POST'])
def upload():
    if request.method == 'POST':
        f = request.files['file']
        if not (f and allowed_file(f.filename)):
            return jsonify({"error": 1001, "msg": "请检查上传的图片类型,仅限于jpg,jpeg,png,gif"})
        upload_path = os.path.join(path, secure_filename(f.filename))
        f.save(upload_path)

        # 图片展示
        files = os.listdir(path)
        fileList = {}
        for file in files:
            file_d = os.path.join(path, file)
            # 执行模型脚本
            res = os.popen("python ./PredictAndMove.py %s" % file_d)
            labels = res.read()
            label = str(labels).strip('\n')
            if label in fileList.keys():
                fileList[label].append({"filename": file, "path": file_d})
            else:
                fileList[label] = [{"filename": file, "path": file_d}]
            # 将字典形式的数据转化为字符串
    return json.dumps(fileList)
  • 定义全局配置、判断后缀名函数以及路由注册
  • 配置信息是以键值对的格式书写,判断文件格式的函数中使用rsplit()方法通过指定分隔符对字符串进行分割并返回一个列表
  • 路由注册通过render_template()方法渲染前端模板(index.html),flask会在templates文件夹内寻找模板文件
  • 调用模型预测的文件

upload()函数为该项目后端的核心模块(详细解释请前往GitHub下载查看源代码)后端整体逻辑为:

保存前端上传的图片–>执行模型预测文件–>返回json数据给前端

深度学习图像分类开源项目(1) - 使用flask部署VGG16神经网络算法模型_第3张图片

补充:若项目运行出现这种报错,是因为路径的问题所导致,建议使用Ubuntu系统运行flask程序,或者将用到的路径全部更换为绝对路径

启动服务器,运行程序

打开终端输入python app.py
深度学习图像分类开源项目(1) - 使用flask部署VGG16神经网络算法模型_第4张图片
此时服务器即为启动状态,打开浏览器,通过127.0.0.1:5000或者ip:5000的方式访问网页,上传图像,进行识别并在前端进行展示
深度学习图像分类开源项目(1) - 使用flask部署VGG16神经网络算法模型_第5张图片

你可能感兴趣的:(深度学习,神经网络算法,Python)