YOLOv5 的 Android 部署,基于 tflite

标签: YOLO android yolo | 发表时间:2022-09-06 22:35 | 作者:迷途小书童
出处:https://xugaoxiang.com

环境

  • window 10 64bit
  • yolov5 v6.2
  • torch1.7.1+cuda101
  • tensorflow-gpu 2.9.1

前言

前文 借助NCNN,在Android上运行YOLOv5目标检测在Android上进行yolov5目标检测,使用torchscript方式,我们分别使用了 ncnntorchscript 这2种方式将 YOLOv5 部署到了 android 手机上。本篇我们将使用另一种方式 tflite 来进行部署,所以,喜欢哪个就用哪个吧。

具体步骤

这里使用最新的 v6.2 版本代码,使用官方的 yolov5s.pt 模型。要使用自己的数据集,需要自己先行训练,训练步骤可以参考文末的链接。

模型转换过程还需要 tensorflow 的环境,安装一下

  pip instal tensorflow-gpu 

然后就可以使用 export.py 脚本进行转换了,命令如下

  python export.py --weights    yolov5s.pt --include tflite --img 416

参数 weights 指定 .pt 模型, --include 参数指定要转换的目标模型, --img 参数指定图片大小

  (pytorch1.7) PS D:\Downloads\yolov5-6.2> python export.py --weights yolov5s.pt --include tflite --img 416
export: data=D:\Downloads\yolov5-6.2\data\coco128.yaml, weights=['yolov5s.pt'], imgsz=[416], batch_size=1, device=cpu, half=False, inplace=False, train=False, keras=False, optimize=False, int8=False, dynamic=False, simplify=False, opset=12, verbose=False, workspace=4, nms=False, agnostic_nms=False, topk_per_class=100, topk_all=100, iou_thres=0.45, conf_thres=0.25, include=['tflite']
YOLOv5  2022-8-17 Python-3.8.8 torch-1.7.1+cu110 CPU

Fusing layers...
YOLOv5s summary: 213 layers, 7225885 parameters, 0 gradients

PyTorch: starting from yolov5s.pt with output shape (1, 10647, 85) (14.1 MB)

TensorFlow SavedModel: starting export with tensorflow 2.9.1...

                 from  n    params  module                                  arguments
2022-08-23 15:19:30.085029: E tensorflow/stream_executor/cuda/cuda_driver.cc:271] failed call to cuInit: CUDA_ERROR_NO_DEVICE: no CUDA-capable device is detected
2022-08-23 15:19:30.091351: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:169] retrieving CUDA diagnostic information for host: USERMIC-Q2OSJCT
2022-08-23 15:19:30.092531: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:176] hostname: USERMIC-Q2OSJCT
2022-08-23 15:19:30.094067: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX AVX2
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
  0                -1  1      3520  models.common.Conv                      [3, 32, 6, 2, 2]
  1                -1  1     18560  models.common.Conv                      [32, 64, 3, 2]
  2                -1  1     18816  models.common.C3                        [64, 64, 1]
  3                -1  1     73984  models.common.Conv                      [64, 128, 3, 2]
  4                -1  1    115712  models.common.C3                        [128, 128, 2]
  5                -1  1    295424  models.common.Conv                      [128, 256, 3, 2]
  6                -1  1    625152  models.common.C3                        [256, 256, 3]
  7                -1  1   1180672  models.common.Conv                      [256, 512, 3, 2]
  8                -1  1   1182720  models.common.C3                        [512, 512, 1]
  9                -1  1    656896  models.common.SPPF                      [512, 512, 5]
 10                -1  1    131584  models.common.Conv                      [512, 256, 1, 1]
 11                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']
 12           [-1, 6]  1         0  models.common.Concat                    [1]
 13                -1  1    361984  models.common.C3                        [512, 256, 1, False]
 14                -1  1     33024  models.common.Conv                      [256, 128, 1, 1]
 15                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']
 16           [-1, 4]  1         0  models.common.Concat                    [1]
 17                -1  1     90880  models.common.C3                        [256, 128, 1, False]
 18                -1  1    147712  models.common.Conv                      [128, 128, 3, 2]
 19          [-1, 14]  1         0  models.common.Concat                    [1]
 20                -1  1    296448  models.common.C3                        [256, 256, 1, False]
 21                -1  1    590336  models.common.Conv                      [256, 256, 3, 2]
 22          [-1, 10]  1         0  models.common.Concat                    [1]
 23                -1  1   1182720  models.common.C3                        [512, 512, 1, False]
 24      [17, 20, 23]  1    229245  models.yolo.Detect                      [80, [[10, 13, 16, 30, 33, 23], [30, 61, 62, 45, 59, 119], [116, 90, 156, 198, 373, 326]], [128, 256, 512], [416, 416]]
Model: "model"
__________________________________________________________________________________________________
 Layer (type)                   Output Shape         Param #     Connected to
==================================================================================================
 input_1 (InputLayer)           [(1, 416, 416, 3)]   0           []

 tf_conv (TFConv)               (1, 208, 208, 32)    3488        ['input_1[0][0]']

 tf_conv_1 (TFConv)             (1, 104, 104, 64)    18496       ['tf_conv[0][0]']

 tfc3 (TFC3)                    (1, 104, 104, 64)    18624       ['tf_conv_1[0][0]']

 tf_conv_7 (TFConv)             (1, 52, 52, 128)     73856       ['tfc3[0][0]']

 tfc3_1 (TFC3)                  (1, 52, 52, 128)     115200      ['tf_conv_7[0][0]']

 tf_conv_15 (TFConv)            (1, 26, 26, 256)     295168      ['tfc3_1[0][0]']

 tfc3_2 (TFC3)                  (1, 26, 26, 256)     623872      ['tf_conv_15[0][0]']

 tf_conv_25 (TFConv)            (1, 13, 13, 512)     1180160     ['tfc3_2[0][0]']

 tfc3_3 (TFC3)                  (1, 13, 13, 512)     1181184     ['tf_conv_25[0][0]']

 tfsppf (TFSPPF)                (1, 13, 13, 512)     656128      ['tfc3_3[0][0]']

 tf_conv_33 (TFConv)            (1, 13, 13, 256)     131328      ['tfsppf[0][0]']

 tf_upsample (TFUpsample)       (1, 26, 26, 256)     0           ['tf_conv_33[0][0]']

 tf_concat (TFConcat)           (1, 26, 26, 512)     0           ['tf_upsample[0][0]',
                                                                  'tfc3_2[0][0]']

 tfc3_4 (TFC3)                  (1, 26, 26, 256)     361216      ['tf_concat[0][0]']

 tf_conv_39 (TFConv)            (1, 26, 26, 128)     32896       ['tfc3_4[0][0]']

 tf_upsample_1 (TFUpsample)     (1, 52, 52, 128)     0           ['tf_conv_39[0][0]']

 tf_concat_1 (TFConcat)         (1, 52, 52, 256)     0           ['tf_upsample_1[0][0]',
                                                                  'tfc3_1[0][0]']

 tfc3_5 (TFC3)                  (1, 52, 52, 128)     90496       ['tf_concat_1[0][0]']

 tf_conv_45 (TFConv)            (1, 26, 26, 128)     147584      ['tfc3_5[0][0]']

 tf_concat_2 (TFConcat)         (1, 26, 26, 256)     0           ['tf_conv_45[0][0]',
                                                                  'tf_conv_39[0][0]']

 tfc3_6 (TFC3)                  (1, 26, 26, 256)     295680      ['tf_concat_2[0][0]']

 tf_conv_51 (TFConv)            (1, 13, 13, 256)     590080      ['tfc3_6[0][0]']

 tf_concat_3 (TFConcat)         (1, 13, 13, 512)     0           ['tf_conv_51[0][0]',
                                                                  'tf_conv_33[0][0]']

 tfc3_7 (TFC3)                  (1, 13, 13, 512)     1181184     ['tf_concat_3[0][0]']

 tf_detect (TFDetect)           ((1, 10647, 85),     229245      ['tfc3_5[0][0]',
                                 [(1, 2704, 3, 85),               'tfc3_6[0][0]',
                                 (1, 676, 3, 85),                 'tfc3_7[0][0]']
                                 (1, 169, 3, 85)])

==================================================================================================
Total params: 7,225,885
Trainable params: 0
Non-trainable params: 7,225,885
__________________________________________________________________________________________________
2022-08-23 15:19:33.627375: I tensorflow/core/grappler/devices.cc:66] Number of eligible GPUs (core count >= 8, compute capability >= 0.0): 0
2022-08-23 15:19:33.627658: I tensorflow/core/grappler/clusters/single_machine.cc:358] Starting new session
Assets written to: yolov5s_saved_model\assets
TensorFlow SavedModel: export success, saved as yolov5s_saved_model (27.8 MB)

TensorFlow Lite: starting export with tensorflow 2.9.1...
Found untraced functions such as tf_conv_2_layer_call_fn, tf_conv_2_layer_call_and_return_conditional_losses, tf_conv_3_layer_call_fn, tf_conv_3_layer_call_and_return_conditional_losses, tf_conv_4_layer_call_fn while saving (showing 5 of 268). These functions will not be directly callable after loading.
Assets written to: C:\Users\ADMINI~1\AppData\Local\Temp\tmp2dfxq2oq\assets
2022-08-23 15:21:33.820763: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:362] Ignored output_format.
2022-08-23 15:21:33.821578: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:365] Ignored drop_control_dependency.
2022-08-23 15:21:33.827268: I tensorflow/cc/saved_model/reader.cc:43] Reading SavedModel from: C:\Users\ADMINI~1\AppData\Local\Temp\tmp2dfxq2oq
2022-08-23 15:21:33.933152: I tensorflow/cc/saved_model/reader.cc:81] Reading meta graph with tags { serve }
2022-08-23 15:21:33.934302: I tensorflow/cc/saved_model/reader.cc:122] Reading SavedModel debug info (if present) from: C:\Users\ADMINI~1\AppData\Local\Temp\tmp2dfxq2oq
2022-08-23 15:21:34.244556: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:354] MLIR V1 optimization pass is not enabled
2022-08-23 15:21:34.301240: I tensorflow/cc/saved_model/loader.cc:228] Restoring SavedModel bundle.
2022-08-23 15:21:35.141922: I tensorflow/cc/saved_model/loader.cc:212] Running initialization op on SavedModel bundle at path: C:\Users\ADMINI~1\AppData\Local\Temp\tmp2dfxq2oq
2022-08-23 15:21:35.504643: I tensorflow/cc/saved_model/loader.cc:301] SavedModel load for tags { serve }; Status: success: OK. Took 1677383 microseconds.
2022-08-23 15:21:36.609861: I tensorflow/compiler/mlir/tensorflow/utils/dump_mlir_util.cc:263] disabling MLIR crash reproducer, set env var `MLIR_CRASH_REPRODUCER_DIRECTORY` to enable.
2022-08-23 15:21:38.044500: I tensorflow/compiler/mlir/lite/flatbuffer_export.cc:1972] Estimated count of arithmetic ops: 7.666 G  ops, equivalently 3.833 G  MACs

Estimated count of arithmetic ops: 7.666 G  ops, equivalently 3.833 G  MACs
TensorFlow Lite: export success, saved as yolov5s-fp16.tflite (13.9 MB)

Export complete (136.66s)
Results saved to D:\Downloads\yolov5-6.2
Detect:          python detect.py --weights yolov5s-fp16.tflite
Validate:        python val.py --weights yolov5s-fp16.tflite
PyTorch Hub:     model = torch.hub.load('ultralytics/yolov5', 'custom', 'yolov5s-fp16.tflite')
Visualize:       https://netron.app

可以看到,转换后的模型是 yolov5s-fp16.tflite,同时,在同层目录下,还有个文件夹 yolov5s_saved_model,里面包含了 .pb 文件,就是 protobuf 文件,这里有个细节,就是 .pt 文件是先被转换成 .pb,然后再转换成 .tflite 的。

接着,使用脚本 detect.py 来验证一下,用上面生成的 .tflite 模型

  python detect.py --weights yolov5s-fp16.tflite --source data/images/bus.jpg --img 416

检测没有问题

有了模型文件,接下来就可以来到 android 端了,我把示例代码上传到了 github 上,可以直接 clone

  git clone https://github.com/xugaoxiang/yolov5_   android_tflite.git

需要替换的是 yolov5_ android_tflite/app/src/main/assets 文件夹下的2个文件, class.txtyolov5s-fp16.tflite

编译后安装到手机,就可以开始进行基于摄像头的目标检测了

参考资料

相关 [yolov5 android tflite] 推荐:

YOLOv5 的 Android 部署,基于 tflite

- - YOLO – 迷途小书童的Note
前文 借助NCNN,在Android上运行YOLOv5目标检测 和 在Android上进行yolov5目标检测,使用torchscript方式,我们分别使用了 ncnn 和 torchscript 这2种方式将 YOLOv5 部署到了. 本篇我们将使用另一种方式 tflite 来进行部署,所以,喜欢哪个就用哪个吧.

YOLOv5发布v6.0版本

- - YOLO – 迷途小书童的Note
就在昨天(2021年10月13日),. yolov5 发布了 V6.0 版本,这个新版本在 V5.0 的基础上集成了很多的新特性,而且在网络结构上也做了微调,引入了全新的更小( Nano )的模型 P5( YOLOv5n) 和 P6( YOLOv5n6). yolov5s 模型的深度( depth ),宽度( width ) 则是从0.5降到了0.25,经过这个操作后,总参数减少了 75%,从 7.5M 缩小到了 1.9M,这样的话,就非常适合于移动端或者是 CPU 的环境.

Streamlit部署YOLOv5目标检测

- - YOLO – 迷途小书童的Note
windows 10 64位. streamlit是一个开源的 python库,它能够快速的帮助我们创建定制化的 web应用,而且还非常便于和他人分享,特别是在机器学习和数据科学领域. 整个过程不需要你了解任何前端的知识,包括 html、 css、 javascript等,对非前端开发人员非常的友好.

使用opencv的dnn模块来进行yolov5的目标检测

- - YOLO – 迷途小书童的Note
yolov5 的 C++ 部署方案中,. opencv 应该是最能被想到的一种,从 3.3 版本后, opencv 就加入了. dnn 这个模块,有了这个模块,很多的机器学习项目就可以通过它来实现部署了,下面我们就来看看具体的实现步骤. 由于 opencv 无法直接读取. yolov5 中的 pt 模型文件,因此,需要将原来的 pt 文件转换成 opencv 能直接读取的 onnx 模型文件.

YOLODet检测效果图-- 包含YOLOv5、YOLOv4、PP-YOLO、YOLOv3等YOLO系列目标检测算法PyTorch版本实现

- - 开源软件 - ITeye博客
YOLODet-PyTorch是端到端基于pytorch框架复现yolo最新算法的目标检测开发套件,旨在帮助开发者更快更好地完成检测模型的训练、精度速度优化到部署全流程. YOLODet-PyTorch以模块化的设计实现了多种主流YOLO目标检测算法,并且提供了丰富的数据增强、网络组件、损失函数等模块.

Android 遥控车

- CasparZ - LinuxTOY
您确定您真的会用 Android 手机玩赛车. 16 岁的法国学生 Jonathan Rico 使用 Android 手机通过蓝牙实现了对改装玩具汽车的遥控. 操控的方式和那些标榜的智能手机游戏一样,使用重力感应,差别是这次控制的是现实世界中的遥控汽车. 收藏到 del.icio.us |.

Android免费?毛

- Ruby - FeedzShare
来自: 36氪 - FeedzShare  . 发布时间:2011年08月17日,  已有 2 人推荐. 微软CEO Steve Ballmer在预测竞争对手产品时通常口无遮拦. 比如他去年抨击Google的Android战略时,很多人都不屑一顾. 接着Android蚕食了微软的地盘,后来又开始侵犯苹果的地盘.

GetEd2k (Android应用)

- 某牢 - eMule Fans 电骡爱好者
GetEd2k是一个Android应用程序,作者是anacletus. 此应用可以帮助你把网页中的电驴(eDonkey) 链接添加到你个人电脑的电驴客户端里,不过前提是你的客户端开启了用于远程控制的Web interface(Web服务器,网页接口,Web界面),当然,eMule(电骡), MLDonkey 和 aMule 都支持该功能,所以这三种主流电驴客户端的用户都可以使用GetEd2k.

Android 4.0发布

- coofucoo - Solidot
Shawn the R0ck 写道 "2011年10月19日早上10点,谷歌与三星联手在香港发布了Android 4.0和Galaxy Nexus. " Android 4.0 的主要特性包括:更精细的UI,加强多任务和通知功能,锁屏下可打开摄像头和浏览通知,改进文本输入和拼写检查;增强视频录制和图像编辑功能,支持剪裁和旋转图片、消除红眼、添加效果等;面部识别解锁;Android Beam允许两台支持NFC的设备之间交换应用程序、联系人、音乐和视频;Wi-Fi Direct,蓝牙HDP,等等.