• -------------------------------------------------------------
  • ====================================

深度学习模型部署全流程-模型部署

技能 dewbay 1年前 (2023-03-01) 829次浏览 已收录 0个评论 扫描二维码

前言
在上一篇文章中详细讲述了模型训练的流程,这篇文章主要介绍模型部署的流程。模型部署通常指通过 C/C++语言能够把 python 框架训练好的模型跑起来,毕竟 C/C++运行效率更高,并且只用提供依赖库和头文件即可移植。

模型部署全流程
1.推理框架
首先要找到一套成熟的推理框架,利用该框架即可完成模型量化,模型推理等功能。在这里推荐自己常用的一套框架腾讯出品的 NCNN 框架,当然也有很多其他的推理框架,但是部署的流程都是大同小异的!
该框架如何编译,如何使用官方都有详细的教程!

深度学习模型部署全流程-模型部署
2.onnx 模型
模型部署之前一般会将我们训练好的模型(xxx.pth)文件转换为 onnx 的模型文件,onnx 为一个中转模型,几乎所有的推理框架都能识别该模型文件,对 onnx 支持度非常高,并将其再次转换为 NCNN 框架能够使用的模型。
转换代码入下

import torch
from flower_cls import Net

model_path = “./model/9.pth”
checkpoint = torch.load(model_path)

net = Net()
net.load_state_dict(checkpoint)
net.eval()

# 指定输入数据维度[N, C, H, W],和训练时保持一致
img = torch.rand([1, 3, 224, 224])

onnx_path = “./model/out.onnx”

output = net(img)
print(output.shape)

out = torch.onnx.export(model=net,
args=torch.randn(1, 3, 224, 224),
f=onnx_path,
input_names=[“input”],
output_names=[“output”],
export_params=True,
verbose=False
)

3.模型转换
将 onnx 模型转换成 NCNN 框架的模型文件,该转换工具推理框架都会提供,输出的 out.param 和 out.bin 就是适用于 NCNN 框架的模型文件了!

深度学习模型部署全流程-模型部署
4.代码实现
通过 NCNN 提供的 API 让模型输出结果,主要步骤为:

  • 1.图像数据读入和与处理,保持和训练时一致即可

// opencv 读取输入图片
cv::Mat img = cv::imread(“1.jpg”, 1);
int w = img.cols;
int h = img.rows;

// 减均值除方差以及缩放操作
ncnn::Mat in = ncnn::Mat::from_pixels_resize(img.data, ncnn::Mat::PIXEL_GRAY, w, h, 224, 224);
float mean[3] = { 0.485*255, 0.456*255, 0.406*255 };
float norm[3] = { 1/0.229/255, 1/0.224/255, 1/0.225/255 };
in.substract_mean_normalize(mean, norm);

  • 2.加载模型文件,NCNN 中 API 都定义好了,调用即可

// 构建 NCNN 的 net,并加载转换好的模型
ncnn::Net net;
net.load_param(“model.param”);
net.load_model(“model.bin”);

  • 3.创建网络层提取器,指定具体提取哪些层的输出结果。(网络层的名称在转换 onnx 模型时会指定,也可以查看.param 文件中的名称,从而找到正确名称,可以查看param 文件解释

// 创建网络提取器,设置网络输入,线程数,light 模式等等
ncnn::Extractor ex = net.create_extractor();

ex.input(“input”, in);
// 调用 extract 接口,完成网络推理,获得输出结果
ncnn::Mat feat;
ex.extract(“output”, feat);

  • 4.将输出转化为所需信息,例如我训练的模型会输出一个[1,1,5]的矩阵,代表 5 个类别的概率,找到最大值即代表该图像所对应的类别,可以看到第二类概率最高

深度学习模型部署全流程-模型部署
5.完整代码

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include “ncnn/net.h”

using namespace cv;
using namespace std;
using namespace ncnn;

int main()
{
// opencv 读取输入图片
cv::Mat img = cv::imread(“1.jpg”, 1);
int w = img.cols;
int h = img.rows;

// 减均值以及缩放操作,最后输入数据的值域为[-1,1]
ncnn::Mat in = ncnn::Mat::from_pixels_resize(img.data, ncnn::Mat::PIXEL_GRAY, w, h, 224, 224);
float mean[3] = { 0.485*255, 0.456*255, 0.406*255 };
float norm[3] = { 1/0.229/255, 1/0.224/255, 1/0.225/255 };
in.substract_mean_normalize(mean, norm);

// 构建 NCNN 的 net,并加载转换好的模型
ncnn::Net net;
net.load_param(“model.param”);
net.load_model(“model.bin”);

// 创建网络提取器,设置网络输入,线程数,light 模式等等
ncnn::Extractor ex = net.create_extractor();

ex.input(“input”, in);
// 调用 extract 接口,完成网络推理,获得输出结果
ncnn::Mat feat;
ex.extract(“output”, feat);

cout<<“输出矩阵维度:”<<endl;
cout<<“c:”<<feat.c<<endl;
cout<<“h:”<<feat.h<<endl;
cout<<“w:”<<feat.w<<endl;

cout<<“各个类别的概率:”<<endl;
cout<<feat[0]<<endl;
cout<<feat[1]<<endl;
cout<<feat[2]<<endl;
cout<<feat[3]<<endl;
cout<<feat[4]<<endl;

return 0;
}

小结
主要介绍了模型部署流程,其中最重要的是 NCNN 框架的使用,多看官方文档,多写写代码就熟悉了,其他框架也都大同小异!


露水湾 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:深度学习模型部署全流程-模型部署
喜欢 (0)
[]
分享 (0)
关于作者:
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址