CSDN下载链接:
https://download.csdn.net/download/qq_38649386/13986438
目录
前言 1
1 EAIDK310开发流程 2
1.1 流程图 2
1.2 必备技能 3
1.3 Tengine说明 3
2 深度学习模型模型转换 4
2.1 保存模型和参数 4
2.1.1 保存模型结构和权重参数 4
2.1.2 只保存模型权重 4
2.1.3 加载别人训练好的模型 4
2.1.4 分别加载网络的结构和参数 4
2.2 pytorch转ONNX 5
2.2.1 保存模型结构和权重参数 5
2.2.2 只保留模型权重 5
2.3 ONNX和onnxruntime 6
2.4 安装ONNX 7
3 Tengine运行深度学习模型 8
3.1 Tengine使用流程图 8
3.2 Tengine Lite整体框架 8
3.3 转换工具制作 9
3.4 Tengine Lite后端处理 9
3.5 Tengine API 10
3.6 深度学习模型测试 10
3.6.1 猫分类测试 10
3.6.2 人脸检测 11
4 opencv图像处理 13
4.1 报错及其解决 13
4.2 opencv库安装 14
4.3 opencv测试 14
5 linux环境开发 15
5.1 开发问题解决 15
5.1.1 寻找安装信息 15
5.1.2 make warring 15
5.1.3 non-existent path 15
5.2 CMake 15
5.2.1 cmake&make关系 15
5.2.2 自动安装 16
5.2.3 手动安装 16
5.2.4 报错及其解决 16
5.4 CMakeList 17
6 学习资料链接 18
前言
对本次实验用的EAIDK310开发板,现已初步掌握其开发流程,包括:
- Linux环境下程序开发流程;
- Tengine加速库安装与使用;
- 深度学习模型文件转换与导入;
- 结合使用opencv对图像预处理。
现就以上内容做初步整理和总结。使用深度学习框架语言Pytorch、OpenCV图像处理选用C++库、Tengine库选用C++的API、主控制程序用C++语言、开发环境为Linux。
未选用python作为开发语言是因为官方Tengine(python版)API文档资料较少,官方资料大部分基于C++语言进行开发。
1 EAIDK310开发流程
1.1 流程图
EAIDK310开发板应用开发流程图如下图:
图 EAIDK310开发流程图
首先,使用pytorch深度学习框架语言训练网络模型,并保存其模型结构和网络参数,文件格式为.pth、.pt或.pkl格式。
其次进行深度学习模型文件格式转换,将上一步骤所得模型文件转换为ONNX文件格式。ONNX(Open Neural Network Exchange)是一个用于表示深度学习模型的标准,可使模型在不同框架之间进行转移。
然后运行官方提供Tengine模型转换工具将ONNX模型文件转换为tmfile文件格式。
完成模型文件转换之后,在EAIDK310开发板烧录Linux系统,并配置相关程序开发环境。运用OpenCV对输入图片做图像预处理,运行Tengine硬件加速库调用深度学习模型文件(tmfile文件),得到网络模型运行结果。
最后根据模型运行结果数据,做相关操作,比如目标检测任务中检测目标的画框操作等。
1.2 必备技能
1.熟悉Linux操作指令以及程序编译;
2.Tengine加速库安装及API使用;
3.深度学习模型训练以及模型文件格式转换;
4.opencv图像处理只是及使用;
5.C++语言程序设计;
1.3 Tengine说明
Tengine 是OPEN AI LAB 针对前端智能设备开发的软件开发包,核心部分是一个轻量级,模块化,高性能的AI 推断引擎,并支持用DLA、GPU、xPU作为硬件加速计算资源异构加速。
图 Tengine主要特点
2 深度学习模型模型转换
2.1 保存模型和参数
.pt .pth .pkl
其实它们并不是在格式上有区别,只是后缀不同而已(仅此而已)。
2.1.1 保存模型结构和权重参数
pytorch模型保存:
- import torch
- torch.save(selfmodel,"save.pt")
pytorch模型加载:
- import torch
- torch.load("save.pt")
2.1.2 只保存模型权重
pytorch模型保存:
- import torch
- torch.save(selfmodel.state_dict(),"save.pt")
pytorch模型加载:
- selfmodel.load_state_dict(torch.load("save.pt"))
2.1.3 加载别人训练好的模型
# 保存和加载整个模型
torch.save(model_object, 'resnet.pth')
model = torch.load('resnet.pth')
2.1.4 分别加载网络的结构和参数
# 将my_resnet模型储存为my_resnet.pth
torch.save(my_resnet.state_dict(), "my_resnet.pth")
# 加载resnet,模型存放在my_resnet.pth
my_resnet.load_state_dict(torch.load("my_resnet.pth"))
其中my_resnet是my_resnet.pth对应的网络结构。
2.2 pytorch转ONNX
2.2.1 保存模型结构和权重参数
- import torch
- torch_model = torch.load("save.pt") # pytorch模型加载
- batch_size = 1 #批处理大小
- input_shape = (3,244,244) #输入数据
- # set the model to inference mode
- torch_model.eval()
- x = torch.randn(batch_size,*input_shape) #生成张量
- export_onnx_file = "test.onnx#目的ONNX文件名
- torch.onnx.export(torch_model,
- x,
- export_onnx_file,
- opset_version=10,
- do_constant_folding=True, # 是否执行常量折叠优化
- input_names=["input"], # 输入名
- output_names=["output"], # 输出名
- dynamic_axes={"input":{0:"batch_size"}, # 批处理变量
- "output":{0:"batch_size"}})
注:dynamic_axes字段用于批处理.若不想支持批处理或固定批处理大小,移除dynamic_axes字段即可.
2.2.2 只保留模型权重
- import torch
- torch_model = selfmodel() # 由研究员提供python.py文件
- batch_size = 1 # 批处理大小
- input_shape = (3, 244, 244) # 输入数据
- # set the model to inference mode
- torch_model.eval()
- x = torch.randn(batch_size,*input_shape) # 生成张量
- export_onnx_file = "test.onnx" # 目的ONNX文件名
- torch.onnx.export(torch_model,
- x,
- export_onnx_file,
- opset_version=10,
- do_constant_folding=True, # 是否执行常量折叠优化
- input_names=["input"], # 输入名
- output_names=["output"], # 输出名
- dynamic_axes={"input":{0:"batch_size"}, # 批处理变量
- "output":{0:"batch_size"}})
2.3 ONNX和onnxruntime
ONNX简介
Open Neural Network Exchange(ONNX,开放神经网络交换)格式,是一个用于表示深度学习模型的标准,可使模型在不同框架之间进行转移(一般用于中间部署阶段)。
目前官方支持加载ONNX模型并进行推理的深度学习框架有: Caffe2, PyTorch, MXNet,ML.NET,TensorRT 和 Microsoft CNTK,并且 TensorFlow 也非官方的支持ONNX。
ONNX Runtime简介
ONNX Runtime是将 ONNX 模型部署到生产环境的跨平台高性能运行引擎。适用于 Linux、Windows 和 Mac。编写C++,它还具有 C、Python 和C# api。 ONNX 运行时为所有 ONNX 规范提供支持,并与不同硬件(如 TensorRT 上的 NVidia Gpu)上的加速器集成
ONNX Runtime与ONNX版本关系
ONNX Runtime 发行版本 |
ONNX发布版本 |
ONNX opset版本 |
ONNX ML opset版本 |
支持的ONNX IR版本 |
1.0.0 |
1.6向下兼容1.2 |
11 |
2 |
6 |
0.5.0 |
1.5向下兼容1.2 |
10 |
1 |
5 |
0.4.0 |
1.5向下兼容1.2 |
10 |
1 |
5 |
0.3.1 |
1.4向下兼容1.2 |
9 |
1 |
3 |
0.2.1 |
1.3向下兼容1.2 |
8 |
1 |
3 |
0.1.5 |
1.3向下兼容1.2 |
8 |
1 |
3 |
2.4 安装ONNX
清华镜像
pip install [镜像] onnx
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple some-package
清华镜像更新pip
升级 pip 到最新的版本 (>=10.0.0) 后进行配置:
pip install pip -U
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
如果您到 pip 默认源的网络连接较差,临时使用本镜像站来升级 pip:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pip -U
豆瓣源镜像
sudo easy_install -i http://pypi.douban.com/simple/ ipython
豆瓣源镜像更新pip
sudo pip install -i [镜像] --trusted-host=pypi.douban.com/simple [packet]
3 Tengine运行深度学习模型
3.1 Tengine使用流程图
图 Tengine使用流程图
调用API初始化Tengine库函数,将训练好的算法模型导入并根据网络节点node创建Graph模型。申请内存空间,然后运行推理引擎得到模型输出结果。结束后,释放内存,防止内存溢出。
3.2 Tengine Lite整体框架
图 Tengine Lite框架
上图中,从上至下依次是,第一层训练模型所用深度学习训练框架,用于训练算法模型;第二层是各个训练框架转换对应的模型文件,保存网络结构以及权重参数;第三层是将训练模型文件转换成Tengine所支持模型文件tmfile格式;第四层是所用推理引擎以及硬件资源包括CPU、GPU、NPU。
3.3 转换工具制作
图 转换工具
由训练框架代码得到相应网络参数保存文件输入给模型转换工具Convert Tool,模型转换工具Convert Tool将网络模型结构作为Node输出,经过open VX将Node连接为网络结构Graph输出,就能的到转换结果tmfile文件格式。
3.4 Tengine Lite后端处理
图 Graph
上一小结得到的tmfile文件经过Serializer,将Graph中的Node分配给不同的数据处理单元,包括CPU、GPU、NPU进行相应数据计算任务。如上图所示,经数据的输入输出的计算任务交由CPU处理,运用数据做推理模型计算任务由NPU完成,达到加速深度学习模型的效果。
3.5 Tengine API
init_tengine(); 初始化Tengine
create_graph(); 链接Tengine模型,创建句柄,链接Tengine和模型文件
get_graph_tensor(); 设置输入
get_graph_input_tensor(); 设置输入
set_tensor_shape(); 设置dim
prerun_graph(); 申请内存空间
set_tensor_buffer(); 设置输入
run_graph(); 运行
get_graph_tensor(); 得到输入
release_graph_tensor(input_tensor); 释放
postrun_graph(graph); 释放
destroy_graph(graph); 释放
release_tengine(); 释放
3.6 深度学习模型测试
3.6.1 猫分类测试
由于系统重装成支持pytorch环境,并且之前C++环境下Tengine测试结果未作相应图片保存,现截取官方文档图片以作参考,后期再做改进。
本次使用为猫种类的分类任务,所用网络为MobileNet,代码大小4.77MB,为输入图片如下:
图 猫图片
进过Tengine模型推理以及后续数据处理,得到如下结果:
3.6.2 人脸检测
C++开发人脸检测算法,代码加模型文件存储大小为1.08MB,为输入图片如下:
图 人脸检测输入
图 人脸检测结果
4 opencv图像处理
4.1 报错及其解决
CV头文件报错
Linux下编写C++代码引用opencv头文件,编译报错 undefined reference to `cv::imread的解决办法
强制链接:
1. 首先确定已安装opencv,可在终端输入命令查看:
$ opencv_version 3.3.1-dev
或输入以下命令查看opencv库的路径:
$ pkg-config --cflags --libs opencv
2. 用GNU命令编译
命令如下:
// 编译生成可执行文件executableFileName
$ g++ source.cpp -o executableFileName $(pkg-config --cflags --libs opencv)
// 运行可以执行文件
$ ./executableFileName
使用CMakeList编译:
1.在项目中新建CMakeLists.txt文件;
2.将以下内容复制粘贴到CMakeLists.txt文件中:
cmake_minimum_required(VERSION 2.2)
project(project)
set(CMAKE_CXX_STANDARD 11)
find_package( OpenCV REQUIRED )
include_directories(${OpenCV_INCLUDE_DIRS}) add_executable(executableFileName source.cpp)
target_link_libraries( executableFileName ${OpenCV_LIBS} )
3.切换到当前工程所在目录下进行编译:
$ cmake .
$ make
$ ./executableFileName
添加路径:
export LD_LIBRARY_PATH=$LD_LIBARARY_PATH:/usr/local/lib
4.2 opencv库安装
安装过程省略,网上有详细安装教程,但是后续会更新安装过程中极易出现的问题以及其结局办法。
C++版本:
方法:进入opencv官方下载OpenCV源代码,拷贝进入EAIDK310开发板,使用make工具编译安装。
python版本:
使用python自带pip工具自动安装。过程中需提前安装各种依赖包。
4.3 opencv测试
图 opencv测试
5 linux环境开发
5.1 开发问题解决
5.1.1 寻找安装信息
安装库信息:pkg-config opencv --libs
安装版本:pkg-config opencv --modversion
安装路径:sudo find / -iname "*opencv*"
sudo find / -iname "*opencv*" > /home/ubuntu/Desktop/opencv_find.txt
5.1.2 make warring
解决make时候出现"make: warning: Clock skew detected. Your build may be incomplete."的问题
意思就是检测到时钟偏差了,主要是两个设备系统之间的时间上存在差距。
解决方案:
find ./ -type f |xargs touch
将所有文件都重新touch一遍,更新到本地系统的时间,再make就没问题了。
5.1.3 non-existent path
问题:
importedtarget “opencv_calib3d” includes non-existent path “//include”.
解决办法:
根据上一小节命令寻找opencv安装库,在相应文件夹下寻找缺失文件,确保存在该文件。
进入“opencv”文件夹,root权限修改OpenCVConfig.cmake文件,
# Provide the include directories to the caller
# set(OpenCV_INCLUDE_DIRS "${OpenCV_CONFIG_PATH}/include" "${OpenCV_CONFIG_PATH}/include/opencv")
set(OpenCV_INCLUDE_DIRS "${OpenCV_CONFIG_PATH}/../../../include" "${OpenCV_CONFIG_PATH}/../../../include/opencv")
将“../”更改为系统对应目录。
5.2 CMake
5.2.1 cmake&make关系
如果源文件太多,一个一个编译时就会特别麻烦,于是人们想到,为什么不设计一种类似批处理的程序,来批处理编译源文件呢,于是就有了make工具,它是一个自动化编译工具,你可以使用一条命令实现完全编译。但是你需要编写一个规则文件,make依据它来批处理编译,这个文件就是makefile,所以编写makefile文件也是一个程序员所必备的技能。
对于一个大工程,编写makefile实在是件复杂的事,于是人们又想,为什么不设计一个工具,读入所有源文件之后,自动生成makefile呢,于是就出现了cmake工具,它能够输出各种各样的makefile或者project文件,从而帮助程序员减轻负担。但是随之而来也就是编写cmakelist文件,它是cmake所依据的规则。所以在编程的世界里没有捷径可走,还是要脚踏实地的。
图 Cpp编译流程图
5.2.2 自动安装
sudo apt install cmake
sudo apt-get install cmake-qt-gui
5.2.3 手动安装
官网下载合适的版本:https://cmake.org/download/
下载后解压,然后进入目录执行:./bootstrap
编译:make -j 8
安装:sudo make install
确认下版本是否已经更新:cmake --version
5.2.4 报错及其解决
ERROR:
Could not find OpenSSL. Install an OpenSSL development package or
configure CMake with -DCMAKE_USE_OPENSSL=OFF to build without OpenSSL.
解决:
apt-get install libssl-dev
rm -f CMakeCache.txt
yum -y install ncurses-devel
yum install openssl-devel
5.4 CMakeList
参考链接:
https://blog.csdn.net/afei__/article/details/81201039
https://www.cnblogs.com/cv-pr/p/6206921.html
6 学习资料链接
310文章链接
EAIDK-310开箱
https://blog.csdn.net/weixin_42905573/article/details/106625661
EAIDK-310板载硬件资源介绍
https://blog.csdn.net/weixin_42905573/article/details/106625668
EAIDK-310烧录Ubuntu系统
https://blog.csdn.net/weixin_42905573/article/details/106625665
EAIDK-310安装浏览器
https://blog.csdn.net/weixin_42905573/article/details/106625664
0 拓展资料
正点原子Linux系列课程专栏
https://www.yuanzige.com/
i.MX6ULL Linux阿尔法开发板
http://www.openedv.com/docs/boards/arm-linux/zdyz-i.mx6ull.html
视频
https://www.bilibili.com/video/BV1yE411h7uQ/?spm_id_from=333.788.videocard.4
Opendv正点原子教程网站
http://www.openedv.com/thread-300792-1-1.html