安卓端使用ncnn部署yolov5(v6.0)

本文介绍如何使用ncnn框架部署YoloV5模型,包括从.pt模型转换为.onnx模型,再进一步转换为ncnn模型(.bin和.param),最后在Android设备上编译并运行模型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ncnn是腾讯公司开源的一个专为手机端极致优化的高性能神经网络前向计算框架。ncnn从设计之初,就深刻考虑手机端的部署和使用,无需第三方依赖,跨平台,手机端cpu的速度快于目前所有已知的开源框架。基于ncnn,开发者能够将深度学习算法轻松移植到手机端高效执行,开发出人工智能APP,将AI带到你的指尖。

ncnn部署yolov5的整体步骤可以分为如下:

  1. 训练.pt,把.pt模型转为.onnx模型
  2. 把.onnx模型转换为ncnn模型(.bin和.param)
  3. Android Studio编译工程成.apk

注意整个流程的版本要求很严格,如果对于ncnn不熟的话,会踩很多坑,本人用yolov5(v6.0)版本的yolov5s.pt模型实验成功。简单列举下我的环境:

  • python==3.6
  • torch==1.10.0+cu111
  • onnx==1.7.0
  • onnx-simplifier==0.4.10
  • onnxruntime==1.10.0

 一、转换.pt到.onnx

github上下载yolov5的6.0版本,下载yolov5s.pt预训练文件,然后调用export.py进行模型转换

python export.py --weights yolov5s.pt --include onnx --img 640 --train --simplify

 --include用来指明转换为什么格式的模型

--train是为了去除后处理,即不直接输出一个分类结果output,而是将三个特征图作为输出

--simplify是简化模型,这里一步完成,不再需要onnxsim进行单独简化。

二、转换onnx到ncnn

ncnn格式的模型包含两个文件,分别是.bin和.param。这里的转换模型可以编译ncnn生成转换工具进行转换,当然,简单粗暴的,我们也可以用现成的工具。

一键转换 Caffe, ONNX, TensorFlow 到 NCNN, MNN, Tengine

转换成功后,把生成的yolov5s-sim-opt.bin和yolov5s-sim-opt.param下载下来即可。这两个文件后续要放在ncnn的AS工程里。

三、Android Studio编译yolov5生成.apk

在github上下载工程 

https://github.com/nihui/ncnn-android-yolov5

然后把此工程用Android Studio打开。注意下载AS时,可以不下载JDK,使用AS自带的JDK就行,然后下载必要的SDK后就可以进行开发了。具体AS下载过程这里不再赘述。

然后来到ncnn的版本发布页,下载编译好的包Releases · Tencent/ncnn · GitHub

 

 下载好后提取到 app/src/main/jni里。

然后把yolov5s-sim-opt.bin和yolov5s-sim-opt.param放在文件夹ncnn-andorid-yolov5/app/src/main/assets里。

此时文件基本准备好了,但需要修改几个地方:

3.1. CMakeLists.txt修改

这个文件定义了工程的名字,编译规则等信息。主要注意下ncnn_DIR的变量修改,要指向刚才下载的ncnn-andoroid-vulkan

3.2. param修改

打开yolov5s-sim-opt.param,找到Reshape行,把0=6400    0=1600    0=400全部修改为0=-1

3.3. yolov5ncnn_jni.cpp修改

这个文件是网络推理的主要文件,需要修改读取ncnn模型的路径,如果是自己训练的模型还要修改class_name的列表, 另外还需修改stride16和stride32的输出

 stride16和stride32的修改根据.param文件里的Permute后的数字进行修改,如下:

  修改完成后,运行程序,就可以愉快的玩耍了。可以直接数据线连接手机进行调试,效果图如下:

 

<think>好的,我现在需要解决用户提出的关于YOLO模型在安卓设备上部署时精度下降的问题。首先,我要理解用户的问题背景。用户可能已经在训练阶段得到了不错的模型精度,但在安卓设备上实际运行时发现精度下降,这可能影响目标检测的效果,比如在番茄病害检测的应用中无法准确识别病害,进而影响后续的补救建议。 接下来,我需要分析可能的原因。根据已有的知识和经验,可能的原因包括模型量化带来的精度损失、硬件性能限制、预处理和后处理的差异、框架兼容性问题,以及训练和部署环境的不一致等。同时,参考用户提供的引用资料,比如引用[1]提到ncnn支持模型量化,可能会影响精度;引用[4]中提到的YOLOv5在移动的应用,可能涉及数据增强和模型优化技巧,这些都需要考虑。 然后,我需要逐一分析每个可能的原因,并给出相应的解决方案。例如,模型量化虽然减少了计算量和内存占用,但可能降低精度,因此可以尝试调整量化参数或使用混合量化。硬件性能方面,安卓设备的算力有限,可能需要简化模型结构或使用更轻量级的版本。预处理和后处理的差异可能导致输入数据不一致,需要确保部署时的处理与训练时一致。框架兼容性方面,不同推理引擎可能有不同的实现,检查层支持情况或更换引擎可能有帮助。此外,训练数据与真实场景的差异,可能需要增加数据增强或进行域适应训练。 还需要考虑用户的具体应用场景,比如番茄病害检测,可能在移动部署时,输入图像的分辨率或光照条件与训练数据不同,导致模型表现下降。这时候可能需要针对移动的环境进行数据增强,或者在应用中加入自动调整图像质量的模块。 然后,我需要将分析的原因和解决方案结构化,确保逻辑清晰,步骤明确。同时,按照用户的要求,生成相关问题,帮助用户进一步探索解决方案。最后,确保回答符合格式要求,如使用中文、正确引用文献、分点列出等,并且避免使用Markdown格式,保持自然的口语化表达。</think>### YOLO模型安卓部署精度下降的原因及解决方案 #### 一、精度下降的常见原因 1. **模型量化损失** 安卓部署使用量化技术(如ncnn支持的8位量化),降低模型精度以提升速度,但可能导致数值范围压缩和激活函数误差积累[^1]。例如,浮点型权重转换为整型时,$w_{int} = \text{round}(w_{float}/scale)$ 会引入舍入误差。 2. **硬件性能限制** 移动GPU/CPU算力不足,导致模型推理时跳过部分计算(如非极大值抑制阈值自动调整),影响检测置信度。例如,ARM Mali GPU的FP16计算可能因精度不足导致边界框坐标偏移。 3. **预处理/后处理不一致** 训练时使用OpenCV的BGR格式和双线性插值,而安卓可能因图像库差异(如Bitmap默认RGB格式)导致输入数据分布偏移,计算误差可达$\Delta= |RGB_{mean} - BGR_{mean}| \geq 15$。 4. **框架兼容性问题** TensorFlow Lite或NCNN对某些算子支持不完善(如自定义SPP层),可能自动替换为近似实现。例如,YOLO的Focus层在部分框架中需拆解为切片+卷积操作,可能损失特征图信息[^3]。 #### 二、解决方案及实施步骤 1. **量化校准优化** - 使用动态范围量化代替全整型量化 ```python converter = tf.lite.TFLiteConverter.from_keras_model(model) converter.optimizations = [tf.lite.Optimize.DEFAULT] # 动态量化 tflite_model = converter.convert() ``` - 对敏感层(如检测头)保留FP16精度,参考ncnn的混合精度量化策略 2. **输入数据对齐** 在安卓严格复现训练预处理流程: ```kotlin val inputTensor = TensorImage(DataType.FLOAT32) inputTensor.load(bitmap) inputTensor = imageProcessor.process(inputTensor) // 必须包含BGR转换、/255归一化等操作 ``` 3. **模型结构适配** - 将YOLOv5的Focus层替换为Conv+BN组合(v6.0后官方推荐) - 使用深度可分离卷积重构检测头,例如将$3\times3$ Conv替换为$DWConv+1\times1 Conv$,参数量减少约$70\%$ 4. **后处理强化** 在Java层实现精确的非极大值抑制: ```java MatrixNMS.builder() .setMinScoreThreshold(0.5f) .setMinSuppressionThreshold(0.6f) .setMaxOutputSize(20) // 与训练时保持一致 .build(); ``` 5. **设备感知训练** 在模型训练阶段引入移动噪声: ```python class MobileAwareAugmentation: def __call__(self, image): image = add_jpeg_compression(image, quality=random.randint(65,85)) # 模拟移动传输压缩 image = add_gaussian_blur(image, radius=random.randint(1,2)) # 模拟摄像头噪声 return image ``` #### 三、验证方法 1. 部署后精度评估流程: $$ \text{精度差异} = \frac{1}{N}\sum_{i=1}^N \left| \frac{AP_{\text{server}} - AP_{\text{mobile}}}{AP_{\text{server}}} \right| \times 100\% $$ 建议差异控制在5%以内 2. 使用TensorFlow Lite的基准测试工具分析层级误差: ```bash benchmark_model --graph=yolo.tflite --enable_op_profiling=true ``` #### 四、典型修复案例 在番茄病害检测项目中[^4],通过以下改进将mAP从0.68提升至0.74: 1. 将输入分辨率从640×640调整为384×384,降低计算需求 2. 对病害特征明显的浅层网络(如P2层)禁用量化 3. 添加移动专用的Mosaic数据增强(包含30%的手机拍摄模拟数据)
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值