Datawhale干货

作者:张强,Datawhale成员

训练目标检测模型并部署到你的嵌入式设备,让边缘设备长“眼睛”。

目标检测的任务是找出图像中所有感兴趣的目标(物体),确定它们的类别和位置,是计算机视觉领域的核心问题之一。目标检测已应用到诸多领域,比如如安防、无人销售、自动驾驶和军事等。在许多情况下,运行目标检测程序的设备并不是常用的电脑,而是仅包含必要外设的嵌入式设备。别看嵌入式设备简陋,但在上面照样能够跑程序,实现我们的想法。设计一个嵌入式AI产品产品,一般会首先考虑成本,在有限的成本内充分利用硬件的性能。因此,不同高低性能的硬件使用场景各不同。

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

本文思维导图如下:

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涉及到的知识广泛,光其中的目标检测和嵌入式编程都可各写一本书。如果你是一个初学者,不要被其中深厚的知识吓到,我们可以“边打仗边学习”,在实践的过程学习。

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

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

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

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

参考资料: https://www.maixhub.com/

↓↓↓点阅读原文获取数据集

目标检测模型从训练到部署!相关推荐

  1. 目标检测模型从训练到部署,其实如此简单

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

  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. 通配符(WildCard)的使用
  2. mac mini 安装mysql数据库
  3. mysql,简单介绍一下索引
  4. css input光标粗细,如何用CSS原生属性caret-color改变input输入框光标颜色
  5. 转 Spring.NET 与 NHibernate 的整合
  6. mysql7种join连接_mysql 重新整理——七种连接join连接[六]
  7. DataTable的Merge\COPY\AcceptChange使用说明
  8. 滴滴司机问我会 LRU 吗?
  9. paip.提升效率---request自动绑定domain object
  10. HashMap中,比较key是否相等为什么要重写equal() 和hashCode()这两个方法?
  11. Delphi接入科大讯飞语音合成SDK
  12. airtest基本介绍
  13. AWS云上混沌工程实践之启动篇
  14. LIFELONG LEARNING WITH DYNAMICALLY EXPANDABLE NETWORKS论文阅读+代码解析
  15. 【软件测试基础】控制用例粒度:测试点的组合和拆分
  16. [渝粤教育] 中原科技学院 设计学和美好生活 参考 资料
  17. 企业项目管理八大经典法宝
  18. 实验四:app内页面跳转
  19. VB程序打包,生成安装程序
  20. 互联网时代结束了吗?

热门文章

  1. Idea项目遇到的错误整理
  2. 【自考】信息系统开发与管理(二)——章节详读
  3. Enterprise Library Configuration DAAB的使用
  4. 【转】PendingIntent的总结
  5. c语言将字母与数字分开存放,2017年计算机二级《C语言》考前提分试题及答案9...
  6. linux sntp 代码,C语言window(linux)平台的SNTP实现
  7. 构筑超异构计算时代,英特尔 AI 全布局
  8. Teradata推出Vantage on Azure,可实现自助配置、快速部署,提供安全、可扩展的高性能分析
  9. B 站神曲damedane:精髓在于换脸,五分钟就能学会
  10. 技术直播:程序员副业的修炼指南!(限免报名)