目录

  • 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_nanoyolox_tiny模型进行部署

1.1 准备Android项目文件

本机为win系统,所以我直接下载压缩文件ncnn-android-yolox.zip,解压后我存放于D:\AndroidStudioProjects\ncnn-android-yolox

android NN 训练_Android

我下载的最新版本,解压后放置在D:\AndroidStudioProjects\ncnn-android-yolox\app\src\main\jni下。

android NN 训练_android NN 训练_02

我随意下了个版本,解压后也放置在D:\AndroidStudioProjects\ncnn-android-yolox\app\src\main\jni下。

android NN 训练_android_03

D:\AndroidStudioProjects\ncnn-android-yolox\app\src\main\jni路径下的文件展示如下:

android NN 训练_opencv_04

1.2 安装和使用Android Studio

需要提前安装JDKAndroid 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选中DNKCMake

注意: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'.的问题。

android NN 训练_android studio_05

  • 修改CMakeLists.txt文件,OpencvNCNN的路径改为你自己的

1.3 apk部署到手机

手机打开开发者模式,并且开启USB调试和USB安装选项(可自行百度自己手机型号怎么开启)。使用USB连接手机选择传输文件(不要选仅充电),在Android Studio依次进行buildrun(看下图),这时手机会弹出窗口提示是否允许安装apk,选择允许,这样就将apk部署到手机上了。

android NN 训练_Android_06

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 pthonnx

使用官方提供的export_onnx.py进行转换

android NN 训练_android_07

2.3 onnx转换为NCNN框架的数据

2.3.1 配置ncnn

ncnn的配置网上有很多都是从头开始构建编译,其实官方有编译好一些版本的ncnn,直接下载下来就行。官方链接:https://github.com/Tencent/ncnn

点击releases,我用的vs2019shared是动态链接版本,我下载了shared版本的。

android NN 训练_android studio_08


android NN 训练_android_09

android NN 训练_android studio_10

解压后随便存放在哪个盘都行,记得在环境变量的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.paramyolox-nano.bin,不要写成yolox_nano.paramyolox_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进行调整,具体操作为:将.paramInput后到第一层ConvolutionSplit层、Crop层和Concat层总共10层替换为1层YoloV5Focus

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
......

android NN 训练_android studio_11

  • 修改后的.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
......

android NN 训练_android_12


使用netron查看结构图:

android NN 训练_Android_13

2.3.4 对算子量化

使用ncnnoptimize.exe进行模型的量化。基于修改后的.param.bin文件,在终端输入:

ncnnoptimize.exe yolox-nano.param yolox-nano.bin yolox-nano.param yolox-nano.bin 65536

量化后的.param文件第2行的数字会自动调整为:

android NN 训练_android studio_14

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方法