洞察纵观鸿蒙next版本,如何凭借FinClip加强小程序的跨平台管理,确保企业在数字化转型中的高效运营和数据安全?
1159
2022-09-06
目标检测模型从训练到部署!
Datawhale干货
作者:张强,Datawhale成员
训练目标检测模型并部署到你的嵌入式设备,让边缘设备长“眼睛”。
目标检测的任务是找出图像中所有感兴趣的目标(物体),确定它们的类别和位置,是计算机视觉领域的核心问题之一。目标检测已应用到诸多领域,比如如安防、无人销售、自动驾驶和军事等。在许多情况下,运行目标检测程序的设备并不是常用的电脑,而是仅包含必要外设的嵌入式设备。别看嵌入式设备简陋,但在上面照样能够跑程序,实现我们的想法。设计一个嵌入式AI产品产品,一般会首先考虑成本,在有限的成本内充分利用硬件的性能。因此,不同高低性能的硬件使用场景各不同。
上篇我们讲到如何部署一个基础CNN分类模型来识别数字,本篇更进一步,将带你训练一个手势检测器,并将其部署到嵌入式设备上。
本文思维导图如下:
01 数据集准备
我们使用一个开源数据集平台:,网站汇总了AI开发者常见的公开数据集,针对我们特定任务,搜索对应的数据集即可,更方便一点,调用其SDK就能直接在线训练。
a. 打开本文对应数据集链接 右上角注册登录
c. fork数据集
KEY = "
然后即可以通过AccessKey可以上传数据、读取数据、使用数据,灵活对接模型开发和训练,与数据pipeline快速集成。
e. AccessKey写入后就可以自由读取数据了。读取前可以开启缓存功能,SDK会在读取data后将其自动缓存至指定路径,此处我们设置缓存路径为data文件夹。
import numpy as npfrom PIL import Imagefrom tensorbay import GASfrom 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.xmin ymin = label_box2d.ymin xmax = label_box2d.xmax ymax = label_box2d.ymax box2d_category = label_box2d.category
02 目标检测模型训练
有两种方法,第一种是使用本地GPU直接训练,若没有GPU课采用方法二。
方法 1 本地GPU进行训练
第一步:拉取docker镜像
# 镜像名称IMAGE="daocloud.io/neucrack/tensorflow-gpu-py3-jupyterlab"# 拉取深度学习平台镜像docker pull $IMAGE# 测试,当日志出现gpu=True表示能成功使用GPUdocker 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 pytorch-k210/handpose_detection/maix_train# 配置NNCASEmkdir -p tools/ncc/ncc_v0.2 && cd tools/ncc/ncc_v0.2wget xvf ncc-linux-x86_64.tar.xzcd ../../
上面的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 - yournamecd /tf
这里笔者选用第二种方式。创建容器时,Docker自动在镜像里创建了一个和本机用户名相同的用户。在容器里运行程序时,强烈建议切换成普通用户运行,否则后期遇到权限问题还需要手动改权限。
第三步:开启训练,使用Yolo V2算法数据集进行训练,具体操作方法为:
# 安装必备的包pip3 install -r requirements.txt -i /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官网,上传数据集准备环节中从格物钛平台缓存的数据集,开始训练;
03 嵌入式设备部署
3.1 开发环境准备
使用kflash作为烧录工具,这个工具图形化和命令行工具都有,选取我们需要的即可。
代码编写方面,使用VSCode编辑Python代码。模型训练好的Python代码还需要微调,这里笔者已经调试好公布在托管的仓库里,大家可以直接拷贝到内存卡,或者串口连接使用。下面介绍如何将训练的模型部署到最终的硬件设备中。
3.2 烧录Micropython固件
第一步 -Micropython固件 到-一个bin文件,这里笔者使用的是minimum_with_kmodel_v4_support
wget 查看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, timeimport KPU as kpuimport gc, sysdef lcd_show_except(e): import uio err_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 1 try: 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 = None task = 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() - t if 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 e finally: 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://maixhub.com/
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~