深度学习实战——不同方式的模型部署(CNNYolo)

Posted @李忆如

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度学习实战——不同方式的模型部署(CNNYolo)相关的知识,希望对你有一定的参考价值。

    忆如完整项目/代码详见github:https://github.com/yiru1225(转载标明出处 勿白嫖 star for projects thanks)

目录

系列文章目录

一、实验综述

1.实验工具及及内容

2.实验数据

3.实验目标

4.实验步骤

二、ML/DL任务综述与模型部署知识补充

1.ML/DL任务综述

2.模型部署知识补充

二、预训练模型知识补充与本地部署实践

1.任务与模型简介

1.1 任务简介

1.2 模型简介

2.本地部署实践

2.1 DL模型的框架选择

2.2 模型定义

2.3 模型训练

2.4 本地部署

三、其他部署方式实践

1.基于CNN的手写数字识别Web网页部署

1.1 Flask简介

1.2 Web网页部署实践

2.基于Yolo v5的多物体检测

2.1 Yolo

2.2 Yolo部署实践

        2.2.1 快速开始

        2.2.2 本地部署

        2.2.3 Web网页部署

        2.2.4 模型训练探索

        2.2.5 云服务器部署

四、真实项目中的模型部署解析

1.智慧养鹅

2.电影推荐系统

五、部署方案补充 

1.通过机器学习平台进行模型部署

1.1 PAI-EAS

1.2 PAI-Blade

2. 参考资料


系列文章目录

本系列博客重点在深度学习相关实践(有问题欢迎在评论区讨论指出,或直接私信联系我)。

第一章  深度学习实战——不同方式的模型部署


梗概

本篇博客主要介绍几种深度预训练模型与模型部署方式,并通过代码实践与真实项目介绍辅助解析(内附代码与数据集)。


一、实验综述

本章主要对实验思路、环境、步骤进行综述,梳理整个实验报告架构与思路,方便定位。

1.实验工具及及内容

本次实验主要使用Pycharm完成几种预训练模型的编写或git/下载调用并分别尝试本地部署(简单部署与中间表示)、Web部署(基于Flask、采用云服务器)等不同方式另外,最近在腾讯实习期间调研了几种主流机器学习平台,在此尝试利用平台工具进行模型部署,还会通过几个本人的真实项目补充一些部署经历(Uni-app、android等移动设备)。

2.实验数据

本次实验大部分数据来自预训练模型官方数据,部分测试数据来源于网络。在真实项目的介绍中,大部分数据来自实地采集与构建,版权属于团队。

3.实验目标

本次实验目标主要是了解深度学习模型部署的基本流程,通过实践完成多种不同的部署方式,并能在真实项目开发中应用。

4.实验步骤

本次实验大致流程如表1所示:

表1 实验1流程

1.实验思路综述

2.ML/DL任务综述与模型部署知识补充

3.预训练模型知识补充与本地部署实践

4.其他部署方式实践

5.真实项目中的模型部署解析

6.模型部署方案补充 

二、ML/DL任务综述与模型部署知识补充

1.ML/DL任务综述

    模型部署实际上是ML(机器学习)/DL(深度学习)任务链路中的一环,为本实验的研究与实践重点,在开始前先对一般ML/DL任务流程做简单补充。

    随着大数据、自然语言处理、计算机视觉领域的不断发展,对多种应用场景下的分类、回归等ML/DL任务在日常生活/公司业务/高校研究中均提出了更多解决方案。对于研究者/开发者而言,有大量ML/DL框架、模型;对其他领域的用户,有大量API/无代码IDE工具与在线平台,大大提高了相关任务效率。

而在ML/DL任务中,最重要的是数据与模型,一般流程总结与简介总结于表2:

表2 ML/DL任务一般流程

输入: 相关数据(集)

过程

1、数据处理

    针对输入数据一般要进行处理,包括但不限于数据清洗、归一化、标注,使数据适配模型输入与实际需求。

2、模型开发

    根据实际任务需求开发模型,或选择已有适配任务的框架/模型调用进行修改。

3、模型训练与评估

    将处理后数据(集)输入模型,进行训练与迭代,并不断对模型效果进行记录与评估,直至达到较优阈值(在对应任务中有较好的表现)。

4、模型部署

    将训练好的较优模型部署到指定环境中进行实际应用(常用模型推理测试)。

5、后处理

    对部署好的模型运行效果进行实际任务的数据检测与分析,并针对出现的问题与局限进行优化。

2.模型部署知识补充

在实际进行模型部署之前,我们先对模型部署的一些核心知识进行补充。

由表2我们知道,模型部署实际上就是将开发、训练、评估好的模型进行调用,并使其在所需任务对应环境下正常运行。不同与软件/DL框架部署,模型部署会面临更多的难题,核心的两个问题如下:

⚪ 运行模型所需的环境难以配置深度学习模型通常是由一些框架编写,比如 PyTorch、TensorFlow。由于框架规模、依赖环境的限制,这些框架不适合在移动设备(手机)、边缘设备(开发板)等生产环境中安装。

⚪ 深度学习模型的结构通常比较庞大,需要大量的算力才能满足实时运行的需求。模型的运行效率需要优化。

因为这些难题的存在,模型部署不能靠简单的环境配置与安装完成。根据相关研究探索,一般的模型部署流程将对训练好的模型进行优化,并通过转化实现运行,如图1所示:

模型在部署后一般会以服务的形式搭载于工具中,故在模型部署中常利用各种前后端框架对功能进行可视化,并对数据进行存储与管理。

此外,随着数据爆炸与云技术的发展,诸多企业提供了带计算与存储资源的云服务器供模型部署、应用上线,以及一站式机器学习平台(Amazon Sage maker、Alibaba PAI、Baidu PaddlePaddle等),其中一般均包含了在线部署工具或部署框架及项目供使用。

图1 模型训练->部署一般流程

Tips:关于其他部署方案与优化在后文详述。

二、预训练模型知识补充与本地部署实践

    在上一章中对ML/DL任务及模型部署的基本知识进行了梳理,自本章开始将正式进行不同方式模型部署的实践,并对使用到的预训练模型进行核心原理的补充。

首先先进行模型本地部署的实践,本章基于CNN的手写数字识别为例。

1.任务与模型简介

在进行模型本地部署前,对本样例的任务与模型进行一定简介。

1.1 任务简介

本章样例选取任务为MNIST数据集上的手写数字识别,MNIST是一个著名的计算机视觉数据集,其包含各种手写数字图片,部分数据可视化如图2所示,本任务即通过设计一个分类模型并使用MNIST数据对其进行训练,得到一个用于识别输入图片中数字的推理模型。

图2 MNIST数据可视化(部分)

1.2 模型简介

本样例以CNN(卷积神经网络)作为分类模型样例,完成手写数字识别的任务。CNN是一种经典的深度学习模型,传统CNN通过输入、卷积、池化、全连接四层高效地完成各种ML/DL任务,实现特征的高效采集与分析。基于CNN的手写数字识别架构如图3所示:

图3 基于CNN的手写数字识别架构

2.本地部署实践

根据第一章第2节补充我们知道,模型部署之前需要定义与训练,即我们要先得到这个模型。根据表2,获取模型的方式一般有调用/下载模型,或自定义模型两种。在本次实践中我们自定义模型并完成本地部署。

2.1 DL模型的框架选择

根据图1我么知道ML/DL任务中常使用框架帮助开发,而在DL模型中,目前最主流的是TensorflowPytorch两种,本样例选择使用TensorFlow框架,但为方便后续Web部署(不需使用Docker),因此选择了是架于TensorFlow、CNTK之上的API,Keras

主要开发环境:Pycharm2020、Tensorflow2.10

2.2 模型定义

根据第一节中的任务与模型简介,定义基于CNN,用MNIST数据集进行训练的分类模型,核心步骤(即模型开发)如表3所示:

表3 基于CNN,用MNIST数据集进行训练的分类模型定义步骤

输入: MNIST数据集(或在代码部分加载)

过程

1、库导入与参数定义

    在开头对需要用到的函数与框架进行导入,并对模型的(超)参数进行定义。

2、数据读取与处理

    对数据集进行下载或导入,并进行图像reshape、数据类型改变(float32)、标准化。

3、模型结构定义

    对模型结构与损失函数定义。

4、训练与评估

    将处理后数据输入定义好模型,进行训练与评估。

输出:模型loss、acc,以及通过评估的模型

在此过程中,代码部分比较重要的是参数与模型的定义,代码如Code1与Code2:

Tips:本处仅做核心代码展示与解析,完整代码与注释详见文件“CNN MNIST Define.py”。

Code1 CNN模型参数

atch_size = 600
img_width, img_height = 28, 28
loss_function = sparse_categorical_crossentropy
no_classes = 10
no_epochs = 1
optimizer = Adam()
validation_split = 0.2
verbosity = 1

Code2 CNN模型结构

model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape))
model.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))
model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dense(no_classes, activation='softmax'))

2.3 模型训练

在定义好模型后,运行相关代码文件进行训练,过程与结果如图4所示:

图4 模型训练过程与结果

分析:根据图4,我们可以看到基于CNN,用MNIST数据集进行训练的分类模型在80轮epoch训练后,正确率98.3%,在本样例中通过评估,保存模型model.h5,用于本地部署。

2.4 本地部署

    本地部署:将模型部署到本地机器中,以离线的方式进行推理。

一般来说,本地部署有两种方式:

    ⚪ 模型直接save和load:调用简单,但未对模型处理,不同机器间可能存在适配问题

    ⚪ TorchScript/ONNX模型导出:以通用的中间表示导出模型,便于部署到不同机器

对于第一种方式,命令如Code3(本样例),Pytorch命令如Code4所示:

Code3 本样例的模型简单本地部署

model.save('model.h5')
model = load_model('model.h5')

Code4 Pytorch的模型简单本地部署

torch.save(model, PATH_TO_MODEL)#保存 
model = torch.load(PATH_TO_MODEL)#加载 

而对于第二种方式,TorchScipt方法主要针对基于Pytorch的模型,故在本部分仅作简单介绍,一般来说,TorchScript提供tracingscripting两种方式,简介如下:

⚪ Tracing方法:生成一个“伪变量”,跟踪模型对输入变量进行的操作。

⚪ Scripting方法:直接检测模型代码,无需伪变量。

两种方法代码类似,以Tracing方法为例,核心代码如Code5所示:

Code5 Tracing方法核心代码

demo_input = torch.ones(x, y, z, d) #生成伪变量
torch.jit.trace(model,demo_input) #生成TorchScipt模型
torch.jit.save(traced_model, 'traced_convnet.pt') #保存
loaded_traced_model = torch.jit.load('traced_convnet.pt') #加载

类似TorchScipt,ONNX也是一种便于部署的模型中间表示,不过适用于多种框架。对于Pytorch而言,ONNX采用Tracing的方式记录模型,故需要“伪输入”,转化核心代码如Code6所示:

Code6 ONNX导出核心代码(Pytorch)

demo_input = torch.ones(x, y, z, d) #生成伪变量
torch.onnx.export(model, demo_input, "convnet.onnx") #转化导出

Tips:ONNX同时提供了prepare()方法将ONNX模型转换为Tensorflow并执行推理,样例代码如Code7所示:

Code7 ONNX转Tf推理样例

import onnx
from onnx_tf.backend import prepare

model_onnx = onnx.load("./convnet.onnx")
tf_rep = prepare(model_onnx)
output = tf_rep.run(input_tensor.unsqueeze(0))
print(output)
# tf_rep.export_graph("./convnet.pb")

而对于Tensorflow转化到ONNX,tensorflow-onnx有几个条目用于转换不同的tensorflow格式的tensorflow模型,本节只讨论“saved_model”,核心代码如Code8,样例输出如图5:

Code8 ONNX导出核心代码(Tensorflow)

!python -m tf2onnx.convert \\
        --saved-model ./output/saved_model \\
        --output ./output/mnist1.onnx \\
        --opset 7

图5 模型转化中间表示输出样例

分析:如图5所示,样例中Tensorflow模型成功转化为ONNX并导出,便于在不同机器上部署、解析与使用。

    Tips:ONXX同样适用于其他框架的转化,且除了本地部署方法提出的两种中间表示,实际上还有其他很多中间表示,在此不做详述。

    至此,完成了本样例任务的模型定义与训练,并使用两种方式进行本地部署。

三、其他部署方式实践

除了本地部署外,还有Web部署、移动应用部署、边缘设备部署等方式,在本章对上一章的样例进行Web网页部署,并对其他预训练模型进行不同方式的部署实践。

1.基于CNN的手写数字识别Web网页部署

Web部署:将模型部署到Web架构中,在服务端完成推理,常见的有以下几种方式:

  1. Flask
  2. Streamlit
  3. Gradio
  4. 厂商Cloud平台(API)

1.1 Flask简介

    本节以Flask为例作为架构搭建样例的Web部署,故在此对Flask做一定补充。

    Flask是一个由Python编写的轻量级Web框架。通过Flask,我们可以将模型推理部署到服务端,以向服务器发送请求的方式执行推理。

服务端部署与本地部署的最大差别在于执行推理的入口不同。对于本地部署,我们只需在本地环境中编写推理脚本并执行即可。Flask服务部署将在我们已经实现的本地部署的基础上完成服务端的架设(对于本样例而言即已经得到了模型文件model.h5)。

一个Flask的最简单样例代码见Code9,效果如图5所示:

Code9 Flask的简单样例

from flask import Flask
# 1. 定义app
app = Flask(__name__)
# 2. 定义函数
@app.route('/')def hello_world():
 return 'hello,word!'
# 3. 定义ip和端口
if __name__ == "__main__":
    app.run(host='127.0.0.1', port=8080)

图5 Flask简单样例效果

1.2 Web网页部署实践

    了解Flask之后,将基于样例模型(基于CNN,MNIST训练的手写数字识别分类模型)在Flask框架下进行网页部署实践。最终效果如图6所示(数字是进入Web页面后用户绘制):

图6 基于CNN的手写数字识别Web网页部署最终效果

接下来开始项目的架构与代码解析,项目整体架构如表4所示

表4 CNN MNIST Web项目架构

.CNN

├── static

      └── index.js                     # 页面按钮的交互

└── style.css                     # 页面的样式

├── templates

└── index.html                   # 页面的框架结构/组件定义

├── CNN MNIST Define.py              # 模型定义

├── flask_CNN.py                      # 模型的Web部署主项目

├── model.h5                          # 训练评估后模型

Tips:完整代码与注释详见项目代码,在此只做关键代码解析。

(1)推理请求

前端三大件(Html、Css、js)的知识与编写并非本实验的重点,在此不做展开。其中部署相关的是推理/预测请求与按钮逻辑的连接,在本部分做一定解析。

本样例中通过Html定义Predict按钮并调用flask_CNN.py中的predict函数完成请求发送与数据接收,其中前端部分相关核心代码如Code10所示:

Code10 前端请求发送与数据接收核心代码

<!-- /container -->

<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>

<script src=" url_for('static',filename='index.js') "></script><script type="text/javascript">

$(".myButton").click(function() 

var $SCRIPT_ROOT =  request.script_root|tojson|safe ;

var canvasObj = document.getElementById("canvas");

var img = canvasObj.toDataURL();

$.ajax(

type: "POST",

url: $SCRIPT_ROOT + "/predict/",

data: img,

success: function(data)

$('#result').text(' Predicted Output: '+data);



);

);

</script>

(2)基于Flask的Web部署

本样例中基于Flask的Web部署代码基本编写在flask_CNN.py,部署流程总结于表5:

表5 基于Flask的CNN Web部署流程

1、初始化

    初始化flask app与与全局变量,并将用户在Web页面画的图生成output.png。

2、搭建前端框架

    根据Html搭建前端,根据Css设计样式,根据js定义逻辑。

3、预测

    定义预测函数,并通过调用模型对处理好图像进行预测,返回结果。

4、输出并展示

    根据预测结果返回数据,展示在前端。

终端输出:供测试,可运行Web端口

根据表5,本样例Web部署核心步骤为预测函数的定义,核心代码如Code11所示(即调用模型预测,在此之前要对用户绘制的图像进行尺度处理,符合模型输入规格):

Code11 Web部署预测

# 调用训练好的模型和并进行预测

global graph

global sess

with graph.as_default():

set_session(sess)

model = load_model('model.h5')

out = model.predict(x)

response = np.argmax(out, axis=1)

return str(response[0])

至此,基于CNN的手写数字识别分类模型在基于Flask的Web部署流程已完成,根据图6可以看到可以较好地对用户绘制图像进行预测,并在Web网页进行展示。

Tips:将项目导入后直接运行flask_CNN.py即可进入Web页面,开箱即用!

2.基于Yolo v5的多物体检测

    除了CNN外,在本节我们尝试使用一些其他的深度模型,也实践一些不同的部署方式,本节样例以基于Yolo v5的多物体检测与识别为例。

2.1 Yolo

    在样例实践前,在此简单介绍一下Yolo算法(尤其是Yolo v5),Yolo是一系列模型,从v1到v8,包含经典与前沿的目标检测算法,适配多种追踪、识别算法。经典的Yolo v1实现核心是图像分割与分块预测(每个网格要预测B个bounding box),如图7所示:

图7 Yolo v1核心原理

而对于Yolo v5,是在Yolo v4上微调的模型(相对灵活),网络架构如图8所示:

图8 Yolo v5网络架构

Tips:Yolo不同版本原理相对复杂,本实验主要做实践探究,在此不做展开。

2.2 Yolo部署实践

Yolo v5官方项目及文档可见:

  1. Github:ultralytics/yolov5: YOLOv5 
  2. Pytorch:YOLOv5 | PyTorch
  3. 模型:https://github.com/ultralytics/yolov5/releases/download/v7.0/yolov5s.pt(直接下载)
  4. 模型选择:Releases · ultralytics/yolov5 (github.com)

    补充:模型默认有yolov5s、m、l、x四种,参数量从小到大。

本地环境(Windows):Pycharm2021、torch1.11.0、torchvision0.12.0(推荐使用Ubuntu)

由于本地部署与Web部署定义与原理在上一章节已详述,故本节只做Yolo模型部署的流程梳理与效果展示,部署流程如表6所示:

表6 Yolo 本地及Web部署流程

1、环境配置:

    Yolo一般基于Pytorch框架,故需先配置Pytorch框架,最好加上CUDA配置,注意框架版本与Pytorch版本的适配性,建议使用Conda管理开发环境。

2、项目与模型下载

    若只是简单使用、部署Yolo模型,可直接下载对应模型;若要基于Yolo优化或基于自己的数据集训练模型需要下载项目导入。

3、使用模型

    对于简单使用,根据上一章节本地部署与Web部署的方法使用yolov5s.pt文件推理;若需要实际开发或优化,根据需求导入文件与数据集训练模型。

4、输出、保存并展示

    若是简单使用,根据预测结果返回图像,保存在本地或展示在前端;若是实际开发或优化,保存训练好通过评估的模型。

输出:本地结果图像/供测试,可运行Web端口/新模型

代码项目架构如图9,简单使用主要关注detect.py即可(推理模块),开发与优化需要使用train.pytest.py进行训练与评估测试。另外,coco是官方提供了检测数据集(Yolo v5在此数据集上表现优秀),requirement.txt为项目配置文件。

图9 Yolo v5项目核心架构

2.2.1 快速开始

若想最快使用Yolo v5完成实际检测任务(不做配置与模型部署),首先可以考虑Pytorch工具箱的在线服务(需要科学上网):

  1. https://colab.research.google.com/github/pytorch/pytorch.github.io/blob/master/assets/hub/ultralytics_yolov5.ipynb(Colab在线编译使用)
  2. YOLOv5 - a Hugging Face Space by pytorch(small Demo)

2.2.2 本地部署

    本地使用有在线导入部署(在代码中下载模型)与项目导入部署(下好模型与源码在本地终端或IDE使用)两种。

在线导入部署代码相对简单(需要科学上网),如Code12所示:

Code12 在线导入部署Yolo v5

import torch

# Model can change name

model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True)

# Images can change path

imgs = ['https://ultralytics.com/images/zidane.jpg']  # batch of images# Inference

results = model(imgs)

# Results

results.print()results.save()  # or .show()

    至此,在线导入部署成功。

而对于项目导入部署相对复杂,但可调参数较多(且对国内用户友好),导入与配置代码如Code13所示:

Code13 Yolo v5导入与配置(本地)

git clone https://github.com/ultralytics/yolov5  # clone

cd yolov5 #本样例使用Pycharm打开

pip install -r requirements.txt  # 配置

    Tips:导入与配置后,还需导入下载的Pt模型文件(若科学上网在项目内会自动下载),或根据model的yaml文件(困难)。

    在环境搭建、项目导入配置、模型文件导入后,便可以轻松开始本地部署/使用,简单样例如Code14所示:

Code14 Yolo v5本地配置/使用(带数据类型)

python detect.py --weights yolov5s.pt --source 0                    # webcam

                            img.jpg                         # image

                            vid.mp4                         # video

                            screen                          # screenshot

                            path/                           # directory

                            list.txt                        # list of images

                            list.streams                    # list of streams

                            'path/*.jpg'                    # glob

                            'https://youtu.be/Zgi9g1ksQHc'  # YouTube

                            'rtsp://example.com/media.mp4'  # RTSP, RTMP, HTTP

    根据Code14在本地对样例图像进行测试,终端运行如图10所示,结果如图11所示:

图10 Yolo v5本地部署测试终端输出

图11 Yolo v5本地部署测试前后对比样例

分析:根据图10与图11,可以看到在本地可以正常调用Yolo v5模型并输出保存检测后图像,验证了本地部署流程的正确性与合理性。

2.2.3 Web网页部署

和上节样例流程类似,本样例的Web部署同样是基于Flask,相关架构与知识不做赘述。

值得一提的是,Yolo v5项目本就自带flask相关api用于Web网页部署的搭建,详见文件夹flask_rest_api。核心用法是通过restapi.py初始化并配置前后端框架,并基于example_request.py的结果启动服务。

    最终部署效果如图12所示:

图12 对于Yolo v5基于Flask的Web部署

分析:如图12,可以看到在Web网页可以正常调用Yolo v5模型并输出保存检测后图像,验证了Web网页部署流程的正确性与合理性。

2.2.4 模型训练探索

在前文中我们知道项目导入后可根据具体需求可在源码项目上训练自己的分类模型,一般流程与表2保持一致。本节我们尝试使用官方数据集coco(带标注多物体数据集)实践训练过程(未修改代码),样例代码如Code15所示:

Code15 Yolo v5训练

python train.py --img 640 --batch 16 --epochs 5 --data coco128.yaml --weights yolov5s.pt

Tips:参数为自定义,为深度模型基本参数与图像数量,可按需修改。

补充:yolov5可以配置wandb,一个动态展示训练状态的web portal,用以观察loss和设备情况,如图13所示:

图13 Yolo v5训练过程可视化

而对训练好的模型测试/评估代码样例可见Code16:

Code16 Yolo v5测试/评估

《自动驾驶中的深度学习模型量化部署加速实战》专栏概述 | 实战教程,开放源码

自动驾驶中的深度学习模型量化部署加速实战

自动驾驶中的深度学习模型量化部署加速实战

Keras深度学习实战——神经网络性能优化技术详解

Keras深度学习实战(26)——文档向量详解

Keras深度学习实战——使用fastText模型构建单词向量

(c)2006-2024 SYSTEM All Rights Reserved IT常识