目录
- 1 利用已有的`yolox_nano`和`yolox_tiny`模型进行部署
- 1.1 准备`Android`项目文件
- 1.2 安装和使用`Android Studio`
- 1.3 `apk`部署到手机
- 2 使用自己训练好的模型进行部署
- 2.1 训练得到`pth`文件
- 2.2 `pth`转`onnx`
- 2.3 `onnx`转换为`NCNN`框架的数据
- 2.3.1 配置`ncnn`
- 2.3.2 `onnx`转换为`.bin`和`.param`文件
- 2.3.3 调整`.param`文件
- 2.3.4 对算子量化
- 2.4 使用自己的模型数据进行部署
- 3 参考
1 利用已有的yolox_nano
和yolox_tiny
模型进行部署
1.1 准备Android
项目文件
- 下载
Android
开发文件(该项目中提供了能直接用的yolox_nano
和yolox_tiny
的模型文件):https://github.com/FeiGeChuanShu/ncnn-android-yolox
本机为win
系统,所以我直接下载压缩文件ncnn-android-yolox.zip
,解压后我存放于D:\AndroidStudioProjects\ncnn-android-yolox
。
- 下载
NCNN
的安卓文件(ncnn-YYYYMMDD-android-vulkan.zip
):https://github.com/Tencent/ncnn/releases
我下载的最新版本,解压后放置在D:\AndroidStudioProjects\ncnn-android-yolox\app\src\main\jni
下。
- 下载
opencv
的安卓文件(opencv-mobile-XYZ-android.zip
):https://github.com/nihui/opencv-mobile
我随意下了个版本,解压后也放置在D:\AndroidStudioProjects\ncnn-android-yolox\app\src\main\jni
下。
D:\AndroidStudioProjects\ncnn-android-yolox\app\src\main\jni
路径下的文件展示如下:
1.2 安装和使用Android Studio
需要提前安装JDK
和Android SDK
JDK
的安装参考:JDK 安装与环境变量配置(Win10详细版)
Android SDK
的安装参考:【Windows系统】Android Studio安装过程遇到SDK tools directory is missing问题
Android Studio
下载地址:https://developer.android.google.cn/studio/,安装可参考:如何安装Android Studio
Android Studio
安装完毕后打开项目文件D:\AndroidStudioProjects\ncnn-android-yolox
File->Settings->Appearance & Behavior ->System Settings->Android SDK
SDK Platform
选择你的安卓手机的版本
SDK Tools
选中DNK
,CMake
注意:DNK
版本别选太高,否则可能出现No toolchains found in the NDK toolchains folder for ABI with prefix: arm-linux-androideabi
问题,我最后选用的是21.3的版本;CMake
选用3.10.2版本,否则会出现诸如- CMake '3.22.1' found in SDK did not match requested version '3.10.2'.
的问题。
- 修改
CMakeLists.txt
文件,Opencv
和NCNN
的路径改为你自己的
1.3 apk
部署到手机
手机打开开发者模式,并且开启USB调试和USB安装选项(可自行百度自己手机型号怎么开启)。使用USB连接手机选择传输文件(不要选仅充电),在Android Studio
依次进行build
和run
(看下图),这时手机会弹出窗口提示是否允许安装apk
,选择允许,这样就将apk
部署到手机上了。
2 使用自己训练好的模型进行部署
在打通了链路后,就可以尝试使用自己的模型进行部署了。
2.1 训练得到pth
文件
YOLOX
训练自己的数据可去网上进行检索,有很多教程。我自己训练了yolox_nano.pth
,其中训练的过程中我有遇到一些奇怪的问题,记录如下,yolox_voc_nano.py
的代码中:
class Exp(MyExp):
def __init__(self):
super(Exp, self).__init__()
self.num_classes = 4 # 自己数据集的类别数量
self.data_num_workers = 0 # 不然会报错OSError: [WinError 1455] 页面文件太小,无法完成操作
self.depth = 0.33
self.width = 0.25
self.input_size = (416, 416)
self.random_size = (10, 20)
self.mosaic_scale = (0.5, 1.5)
self.test_size = (416, 416)
self.max_epoch = 100
# self.mosaic_prob = 0.5 // 这个不注释后就会出现AttributeError: 'int' object has no attribute 'numel'
self.enable_mixup = False
self.exp_name = os.path.split(os.path.realpath(__file__))[1].split(".")[0]
"""
......
"""
2.2 pth
转onnx
使用官方提供的export_onnx.py
进行转换
2.3 onnx
转换为NCNN
框架的数据
2.3.1 配置ncnn
ncnn
的配置网上有很多都是从头开始构建编译,其实官方有编译好一些版本的ncnn
,直接下载下来就行。官方链接:https://github.com/Tencent/ncnn
点击releases
,我用的vs2019
,shared
是动态链接版本,我下载了shared
版本的。
解压后随便存放在哪个盘都行,记得在环境变量的path
中把bin
路径添加进去,并且由于我opencv
版本使用的x64
的关系,所以我添加的路径为:D:\ncnn-20221128-windows-vs2019-shared\x64\bin
。
2.3.2 onnx
转换为.bin
和.param
文件
先把上面得到的yolox_nano.onnx
复制到ncnn
目录(D:\ncnn-20221128-windows-vs2019-shared\x64\bin
)下,现在需要将onnx
格式的模型转成ncnn
能够加载的.bin
和.param
:
【这里注意转换得到的名字yolox-nano.param
和yolox-nano.bin
,不要写成yolox_nano.param
和yolox_nano.bin
不然后面会出现软件闪退】
cd D:\ncnn-20221128-windows-vs2019-shared\x64\bin
onnx2ncnn.exe yolox_nano.onnx yolox-nano.param yolox-nano.bin
会出现下面的警告,这是因为ncnn
不支持Focus
模块,但没关系
Unsupported slice step !
Unsupported slice step !
Unsupported slice step !
Unsupported slice step !
Unsupported slice step !
Unsupported slice step !
Unsupported slice step !
Unsupported slice step !
2.3.3 调整.param
文件
因为ncnn
不支持Focus
模块,所以需要对yolox-nano.param
进行调整,具体操作为:将.param
中Input
后到第一层Convolution
的Split
层、Crop
层和Concat
层总共10层替换为1层YoloV5Focus
- 调整前的
.param
(正常的Crop
是有8层,如果出现只有4层,表示onnx和onnx-simplifer版本太低了,参考export_onnx导入的onnx模型与官方模型不一致进行修改):
7767517
295 328
Input images 0 1 images
Split splitncnn_input0 1 4 images images_splitncnn_0 images_splitncnn_1 images_splitncnn_2 images_splitncnn_3
Crop Slice_4 1 1 images_splitncnn_3 647 -23309=1,0 -23310=1,2147483647 -23311=1,1
Crop Slice_9 1 1 647 652 -23309=1,0 -23310=1,2147483647 -23311=1,2
Crop Slice_14 1 1 images_splitncnn_2 657 -23309=1,0 -23310=1,2147483647 -23311=1,1
Crop Slice_19 1 1 657 662 -23309=1,1 -23310=1,2147483647 -23311=1,2
Crop Slice_24 1 1 images_splitncnn_1 667 -23309=1,1 -23310=1,2147483647 -23311=1,1
Crop Slice_29 1 1 667 672 -23309=1,0 -23310=1,2147483647 -23311=1,2
Crop Slice_34 1 1 images_splitncnn_0 677 -23309=1,1 -23310=1,2147483647 -23311=1,1
Crop Slice_39 1 1 677 682 -23309=1,1 -23310=1,2147483647 -23311=1,2
Concat Concat_40 4 1 652 672 662 682 683 0=0
Convolution Conv_41 1 1 683 1177 0=16 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=1728
Swish Mul_43 1 1 1177 687
ConvolutionDepthWise Conv_44 1 1 687 1180 0=16 1=3 11=3 2=1 12=1 3=2 13=2 4=1 14=1 15=1 16=1 5=1 6=144 7=16
Swish Mul_46 1 1 1180 691
Convolution Conv_47 1 1 691 1183 0=32 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=512
......
- 修改后的
.param
7767517
286 328
Input images 0 1 images
YoloV5Focus focus 1 1 images 683
Convolution Conv_41 1 1 683 1177 0=16 1=3 4=1 5=1 6=1728
Swish Mul_43 1 1 1177 687
ConvolutionDepthWise Conv_44 1 1 687 1180 0=16 1=3 3=2 4=1 5=1 6=144 7=16
Swish Mul_46 1 1 1180 691
Convolution Conv_47 1 1 691 1183 0=32 1=1 5=1 6=512
......
使用netron查看结构图:
2.3.4 对算子量化
使用ncnnoptimize.exe
进行模型的量化。基于修改后的.param
和.bin
文件,在终端输入:
ncnnoptimize.exe yolox-nano.param yolox-nano.bin yolox-nano.param yolox-nano.bin 65536
量化后的.param
文件第2行的数字会自动调整为:
2.4 使用自己的模型数据进行部署
- 将量化后得到的
.param
和.bin
文件复制到D:\AndroidStudioProjects\ncnn-android-yolox\app\src\main\assets
路径下,替代掉原有的文件 - 修改
yolox.cpp
中的class_names
为自己的类别名 - 然后再进行上方的1.3步骤(
apk
部署到手机)就可将自己的模型部署到手机上了
😱如果出现手机有图像但是并没有检测框的情况,请进行下面操作再重新进行1.3步骤
// yolox.cpp
// so for 0-255 input image, rgb_mean should multiply 255 and norm should div by std.
// new release of yolox has deleted this preprocess,if you are using new release please don't use this preprocess.
//in_pad.substract_mean_normalize(mean_vals, norm_vals); // 将这句话注释掉
3 参考
YOLOX模型部署Android端-NCNN方法