目标检测的任务是找出图像中所有感兴趣的目标(物体),确定它们的类别和位置,是计算机视觉领域的核心问题之一。目标检测已应用到诸多领域,比如如安防、无人销售、自动驾驶和军事等。

在许多情况下,运行目标检测程序的设备并不是常用的电脑,而是仅包含必要外设的嵌入式设备。别看嵌入式设备简陋,但在上面照样能够跑程序,实现我们的想法。设计一个嵌入式AI产品产品,一般会首先考虑成本,在有限的成本内充分利用硬件的性能。因此,不同高低性能的硬件使用场景各不同。

我们讲到如何部署一个基础CNN分类模型来识别数字,本篇更进一步,将带你训练一个手势检测器,并将其部署到嵌入式设备上。

本文思维导图如下:

干货推荐

  • 浙大博士导师深度整理:Tensorflow 和 Pytorch 的笔记(包含经典项目实战)
  • 值得收藏,这份机器学习算法资料着实太香
  • 比 PyTorch 的官方文档还香啊,吃透PyTorch中文版来了
  • 赶快收藏,PyTorch 常用代码段PDF合辑版来了

01 数据集准备

我们使用一个开源数据集平台:https://gas.graviti.com/ ,网站汇总了AI开发者常见的公开数据集,针对我们特定任务,搜索对应的数据集即可,更方便一点,调用其SDK就能直接在线训练。

a. 打开本文对应数据集链接 https://gas.graviti.com/dataset/datawhale/HandPoseforK210

b. 右上角注册登录

c. fork数据集

d. 点击网页上方Developer Tools,获取使用SDK所需的AccessKey,获取到 AccessKey 后,将其存在项目根目录的gas_key.py里:

KEY = "<Your-Key>"

然后即可以通过AccessKey可以上传数据、读取数据、使用数据,灵活对接模型开发和训练,与数据pipeline快速集成。

e. AccessKey写入后就可以自由读取数据了。读取前可以开启缓存功能,SDK会在读取data后将其自动缓存至指定路径,此处我们设置缓存路径为data文件夹。

import numpy as np
from PIL import Imagefrom tensorbay import GAS
from tensorbay.dataset import DatasetKEY = '复制你的ACCESSKEY替换'
def read_gas_image(data):with data.open() as fp:image = Image.open(fp)image.load()return np.array(image)gas = GAS(KEY)
dataset = Dataset("HandPose", gas)
dataset.enable_cache("data")
segments = dataset.keys()
segment = dataset["train"]for data in segment:# 获取的Numpy格式的图片数据image = read_gas_image(data)# 标签数据for label_box2d in data.label.box2d:xmin = label_box2d.xminymin = label_box2d.yminxmax = label_box2d.xmaxymax = label_box2d.ymaxbox2d_category = label_box2d.category

02 目标检测模型训练

有两种方法,第一种是使用本地GPU直接训练,若没有GPU课采用方法二。

方法 1 本地GPU进行训练

第一步: 拉取docker镜像

# 镜像名称
IMAGE="daocloud.io/neucrack/tensorflow-gpu-py3-jupyterlab"
# 拉取深度学习平台镜像
docker pull $IMAGE
# 测试,当日志出现gpu=True表示能成功使用GPU
docker run --gpus all -it --rm $IMAGE python -c "import tensorflow as tf; print('-----version:{}, gpu:{}, 1+2={}'.format(tf.__version__, tf.test.is_gpu_available(), tf.add(1, 2).numpy()) );"

第二步: 拉取本文代码,配置NNCASE,开启docker容器

git clone https://github.com/QiangZiBro/pytorch-k210
cd pytorch-k210/handpose_detection/maix_train
# 配置NNCASE
mkdir -p tools/ncc/ncc_v0.2 && cd tools/ncc/ncc_v0.2
wget https://github.com/kendryte/nncase/releases/download/v0.2.0-beta4/ncc_linux_x86_64.tar.xz
tar xvf ncc-linux-x86_64.tar.xz
cd ../../

上面的NNCASE只需要下载、解压即可,我们接下来使用Docker构建一个Linux虚拟容器环境,如下面命令开启环境:

# 开启容器
docker run --gpus all --name jupyterlab-gpu -it -p 8889:8889 -e USER_NAME=$USER -e USER_ID=`id -u $USER` -e GROUP_NAME=`id -gn $USER` -e GROUP_ID=`id -g $USER` -v `pwd`:/tf $IMAGE

开启容器后,有两种操作方式供选择

  • 第一种,使用jupyter-notebook运行

  • 第二种,直接进入容器内部

    docker exec -it jupyterlab-gpu /bin/bash
    # 在容器内部,建议切换到普通用户运行
    su - yourname
    cd /tf
    

这里笔者选用第二种方式。创建容器时,Docker自动在镜像里创建了一个和本机用户名相同的用户。在容器里运行程序时,强烈建议切换成普通用户运行,否则后期遇到权限问题还需要手动改权限。

第三步: 开启训练,使用Yolo V2算法数据集进行训练,具体操作方法为:

# 安装必备的包
pip3 install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/cd /handpose_detection/maix_train
# 初始化
python3 train.py init
# 开始训练
python3 train.py -t detector -d datasets/game train

运行上述命令即使用maix_train工具箱开始训练,这个程序能一键完成训练、参数转换、量化等功能

使用100个Epoch进行训练,得到的结果生成在out文件下。

方法2 使用在线GPU进行训练

运行时默认调用GPU训练,如果没有GPU则使用CPU,训练时间相对CPU较慢。没有GPU的小伙伴也不用担心,可以直接将数据集上传到maixhub进行在线训练。这里的限制是需要有一块K210开发板,并且数据集大小在20M以内。下面简要介绍方法:

第一步, 打开maixhub官网,https://www.maixhub.com/ModelTraining,注册、登录,根据官网提示获得机器码;

第二步, 上传数据集准备环节中从格物钛平台缓存的数据集,开始训练;

大概二十分钟后,模型就训练好了,点击Download下载训练的模型。这里的结果和上面的out文件夹下的压缩文件一样。

03 嵌入式设备部署

3.1 开发环境准备

使用kflash作为烧录工具,这个工具图形化和命令行工具都有,选取我们需要的即可。

代码编写方面,使用VSCode编辑Python代码。模型训练好的Python代码还需要微调,这里笔者已经调试好公布在托管的仓库里,大家可以直接拷贝到内存卡,或者串口连接使用。下面介绍如何将训练的模型部署到最终的硬件设备中。

3.2 烧录Micropython固件

第一步 下载Micropython固件 到https://dl.sipeed.com/shareURL/MAIX/MaixPy/release/master 下载一个bin文件,这里笔者使用的是minimum_with_kmodel_v4_support

wget https://dl.sipeed.com/fileList/MAIX/MaixPy/release/master/maixpy_v0.6.2_72_g22a8555b5/maixpy_v0.6.2_72_g22a8555b5_minimum_with_kmodel_v4_support.bin

第二步 查看K210的串口号,以笔者使用的MacOS为例:

ls /dev/cu.usbserial-*
# /dev/cu.usbserial-14330

第三步 烧录

使用命令行进行烧录示例

kflash  -p /dev/cu.usbserial-14330 -b 115200 -t maixpy_v0.6.2_72_g22a8555b5_minimum_with_kmodel_v4_support.bin

使用kflash图形界面的烧录示例

3.3 烧录目标检测模型参数

有两种方式将训练模型参数部署到嵌入式设备上:

  • 使用程序烧录器直接烧录到flash中的一片地址,在程序中直接加载这块地址指向的内存

  • 将模型参数拷贝在SD卡上,在程序中从SD卡加载

对于第一种方法,我们一般将模型参数烧录在以0x30000为开始的内存上,结尾不需要制定,程序底层会自己判断结束点。因此,在烧录时,只需要在kflash GUI的0x00000改为0x30000即可。当然,你也可以使用命令行烧录,同样的效果。

对于第二种方法,直接将上面训练好的所用文件拷贝到SD卡,再插入K210开发板即可。

3.4 模型推理脚本

Micropython固件和模型参数烧录成功后,使用下面脚本便可以加载脚本,进行检测了。建议先打开串口,将程序复制过去运行,观察运行结果,调试到正常运行后再放置到SD卡中

第一步: 复制下面代码

# object detector boot.py
# generated by maixhub.comimport sensor, image, lcd, time
import KPU as kpu
import gc, sysdef lcd_show_except(e):import uioerr_str = uio.StringIO()sys.print_exception(e, err_str)err_str = err_str.getvalue()img = image.Image(size=(240,240))img.draw_string(0, 10, err_str, scale=1, color=(0xff,0x00,0x00))lcd.display(img)def main(anchors, labels = None, model_addr="/sd/m.kmodel", sensor_window=(240,240), lcd_rotation=0, sensor_hmirror=False, sensor_vflip=False):sensor.reset()sensor.set_pixformat(sensor.RGB565)sensor.set_framesize(sensor.QVGA)sensor.set_windowing(sensor_window)sensor.set_hmirror(sensor_hmirror)sensor.set_vflip(sensor_vflip)sensor.run(1)lcd.init(type=1, invert=True)lcd.rotation(lcd_rotation)lcd.clear(lcd.WHITE)if not labels:with open('labels.txt','r') as f:exec(f.read())if not labels:print("no labels.txt")img = image.Image(size=(320, 240))img.draw_string(90, 110, "no labels.txt", color=(255, 0, 0), scale=2)lcd.display(img)return 1try:img = image.Image("startup.jpg")lcd.display(img)except Exception:img = image.Image(size=(320, 240))img.draw_string(90, 110, "loading model...", color=(255, 255, 255), scale=2)lcd.display(img)try:task = Nonetask = kpu.load(model_addr)kpu.init_yolo2(task, 0.5, 0.3, 5, anchors) # threshold:[0,1], nms_value: [0, 1]while(True):img = sensor.snapshot()t = time.ticks_ms()objects = kpu.run_yolo2(task, img)t = time.ticks_ms() - tif objects:for obj in objects:pos = obj.rect()img.draw_rectangle(pos)img.draw_string(pos[0], pos[1], "%s : %.2f" %(labels[obj.classid()], obj.value()), scale=2, color=(255, 0, 0))img.draw_string(0, 200, "t:%dms" %(t), scale=2, color=(255, 0, 0))lcd.display(img)except Exception as e:raise efinally:if not task is None:kpu.deinit(task)if __name__ == "__main__":try:labels = ["raised_fist", "victory_hand", "hand_with_fingers_splayed"]anchors = [3.96875, 8.8125, 3.25, 7.5, 4.4375, 6.4375, 3.3125, 5.15625, 6.125, 8.25]#main(anchors = anchors, labels=labels, model_addr=0x300000, lcd_rotation=0)main(anchors = anchors, labels=labels, model_addr="/sd/m.kmodel")except Exception as e:sys.print_exception(e)lcd_show_except(e)finally:gc.collect()

上面代码有几点注意:

  • 使用雅博的K210开发板需要在LCD初始化将invert参数置为True,即lcd.init(type=1, invert=True)

  • main函数有两种运行方式,分别表示从flash加载模型和从SD卡加载模型

第二步: 打开终端,Mac上可以使用screen和串口进行通信

screen /dev/cu.usbserial-14340 115200
# 串口号不一定一样

(常用功能退出:先ctrl+a,再按k键,按y确认)

如果成功会出现下面结果:

第三步: 拷贝程序通过串口进行交互式运行

首先按Ctrl+E,进入拷贝模式,出现下面结果

复制后Ctrl+D即可开始运行,程序运行无误后,拷贝全部文件到SD卡。程序运行成功后,效果如下

总结和思考

本文提供了一个从图像深度学习算法训练的开始,最终将其部署在嵌入式设备K210上。嵌入式AI涉及到的知识广泛,光其中的目标检测和嵌入式编程都可各写一本书。如果你是一个初学者,不要被其中深厚的知识吓到,我们可以“边打仗边学习”,在实践的过程学习。

下面提供几个小问题,以供课后思考:

  • 有哪些可能的方法能够提升识别的准确率?

  • 能否从数据本身出发,提高识别的性能?

  • 本文的神经网络参数的参数转换流程是怎样的?

目标检测模型从训练到部署,其实如此简单相关推荐

  1. 目标检测模型从训练到部署!

    Datawhale干货 作者:张强,Datawhale成员 训练目标检测模型并部署到你的嵌入式设备,让边缘设备长"眼睛". 目标检测的任务是找出图像中所有感兴趣的目标(物体),确定 ...

  2. 基于VS2017+OpenCV,C++搭建NanoDet-Plus轻量级目标检测模型并训练(二)

    1.数据准备 标签格式是json,分成训练集(train)和验证集(val),分别存放图和对应的标签文件,利用如下代码将单个的json文件转成coco格式的json,代码如下: # -*- codin ...

  3. 手把手教你训练自己的目标检测模型(SSD篇)

    目标检测是AI的一项重要应用,通过目标检测模型能在图像中把人.动物.汽车.飞机等目标物体检测出来,甚至还能将物体的轮廓描绘出来,就像下面这张图,是不是很酷炫呢,嘿嘿 在动手训练自己的目标检测模型之前, ...

  4. 大连理工IIAU Lab提出SSLSOD:自监督预训练的RGB-D显著性目标检测模型(AAAI 22)

    作者丨Lart 编辑丨极市平台 导读 本文在显著性目标检测任务(SOD)中,首次引入自监督预训练.凭借提出的有效的前置任务(pretext task),在仅使用少量无标签的RGB-D数据进行预训练的情 ...

  5. 使用TF lite 优化 MobileDet 目标检测模型部署

    文 / Sayak Paul,Google Developer Expert 今年,来自威斯康星大学麦迪逊分校和 Google 的研究人员发表了他们在 MobileDet 上所做的研究工作.他们在 M ...

  6. Tensorflow object detection API训练自己的目标检测模型 详细配置教程 (一)

    Tensorflow object detection API 简单介绍Tensorflow object detection API: 这个API是基于tensorflow构造的开源框架,易于构建. ...

  7. 树莓派4B部署YOLOv5目标检测模型部署(包含加速方法以及模型训练方法总结)

    树莓派4B部署YOLOv5目标检测模型部署 1.工作内容简介: (1)训练鱼类目标识别模型.首先建立水下鱼类目标数据集,由于目前国内暂时并没有可用红鳍东方鲀标注数据集,本文利用Labelimage软件 ...

  8. (二)目标检测模型的评测与训练技巧

    转载自知乎:https://zhuanlan.zhihu.com/p/34142321 关于作者: @李家丞同济大学数学系本科在读,现为格灵深瞳算法部实习生. -------------------- ...

  9. 使用opencv训练目标检测模型基于cascade模型

    使用opencv训练目标检测模型基于cascade模型 基于Haar特征的cascade分类器(classifiers) 是Paul Viola和 Michael Jone在2001年,论文" ...

最新文章

  1. [转载] 马化腾-“杀人的网络,互联网的大是大非问题”专访腾讯董事会主席兼CEO马化腾...
  2. 来自十年互联网人的大厂等级晋升攻略
  3. 抓住语音社交风口,1天快速搭建语音聊天室
  4. Windows Message Queue(优先队列)
  5. Quartz执行周期配置
  6. Spark对Kafka两种连接方式的对比——Receiver和Direct
  7. 袋鼠云大数据面试题回忆
  8. 手动挡五个档位示意图_汽车档位越多越好?听听专业回答
  9. 前端学习(2567):指令的本质
  10. SPH(光滑粒子流体动力学)流体模拟实现二:SPH算法(3)-光滑核函数
  11. Python id(obj), ==, is 三者之间的区别
  12. “背叛”乔布斯,库克做对了
  13. 那个马斯克的小迷弟开始讲深度学习了,课程视频+PPT已放出
  14. 2.maven 安装配置
  15. 关于MySQL latch争用深入分析与判断
  16. STC12LE5612AD芯片使用心得(一)芯片介绍
  17. RN:真机调试无线调试
  18. 软考信息系统监理师:2016年4月22日作业
  19. MATLAB特殊矩阵的构造
  20. 量子笔记:单比特量子门、泡利矩阵

热门文章

  1. lammps教程:velocity拉伸“拉不动”的原因探讨及解决方案
  2. matlab cody学习笔记 day18
  3. 程序员该如何学习技术
  4. 深度解密Mysql数据库索引
  5. 活动图的制作非常简单,只需5个步骤即可完成精美互动图!
  6. dell台式机安装centos7网卡设置
  7. 微信读书vscode插件_推荐 10 款有趣的 VSCode 插件
  8. 如何刷鸿蒙OS,普通安卓手机如何刷鸿蒙系统?
  9. Android 面经【持续更新.....】
  10. 第二证券|下周解禁市值超980亿元,多家机构参与解禁股评级