0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

RT106x的小车上部署AI实施设计案例分析

电子设计 来源:CSDN 博主 作者:卓晴 2020-12-28 16:12 次阅读

继卓大大发布了推文“基于RT106x电磁智能AI算法”,并将此列为2020年智能车竞赛的比赛项目之一以后,AI算法智能车受到了广大同学和专家的热烈讨论。很多同学都想在自己的赛道上感受一下AI的魅力,但苦于没有文档和工具而无从下手。

在这里向大家介绍我们在RT106x的小车上部署实施AI的方法,以及一个base line的电磁导引神经网络模型,希望能抛砖引玉,激发同学们开动脑筋,将AI在电磁智能车上的应用发扬光大。

先期准备

硬件条件

话不多说,首先必须有电磁智能车一辆,无线透传模块用于采集训练数据(感谢逐飞科技友情赞助)。

下图是我们使用的车模,其中红色框内车身的7个电感,是AI算法中电磁车运行导向的输入电感。

AI电磁实验的车模及其传感器配置

蓝色框内的电感是抓取训练数据时的导航电感,在AI算法中并不使用(在模型部署成功后可以拆除)。

软件环境

Python:3.7.3

Keras:2.2.4

TensorFlow:1.13.1

模型设计

模型的目的是通过车身的电感值来推导出对小车舵机的转向控制命令,这是典型的回归问题。

我们训练了简易的Baseline模型,结构如下:

使用Netron软件显示的网络结构图

如图所示,模型只使用了Dense算子——也就是全连接层,在一些文献里称之为多层感知机。模型使用最新一笔7个电感的读数,参数19,301个,内存需求很小,运算速度快,用RT1060哪怕是按16位量化也完全无压力。

不过,各位同学不要以为设计完了模型就万事大吉了,以为有了AI模型就可以忘掉经典算法中调参的痛苦。小编可以负责任地告诉你,痛苦才刚刚开始……

采集数据,训练模型

数据采集和处理

众所周知训练数据是机器学习的重中之重,没有完备的数据AI模型只不过是镜中花水中月,没有任何意义。训练数据对于模型而言就是韩信点兵多多益善,但也一定要小心不要引入错误数据,错误数据会让你出轨~啊不,是让小车出轨,然后就无迹可寻了。小编为了训练数据不知道掉了多少头发,死了多少脑细胞。

我们获取训练数据的方法是:小车运行经典导航算法,由小车的前置电感导航,实时抓取车身的电感数据,转向数据,再通过无线透传模块发送到PC端,PC上的串口工具把数据保存成文本格式。

怎么把文本格式的数据转换成训练数据呢?这就要借助强大的Python了,在脚本里读入文本文件,把7组AD值作为x_train、x_test,对应的转向值pwm作为y_train、y_test,并保存成numpy数组文件以方便训练脚本调用,建议生成四个文件x_train.npy、x_test.npy、y_train.npy、y_test.npy,注意数据格式要符合模型结构,数据范围要压缩至-128~127之间用于制作测试文件。

在数据转换时需要对AD值做一个简单滤波。以下是我们使用的滤波算法仅供参考。

简单的滤波算法

模型训练

在训练脚本读取训练数据numpy文件,并把数据范围标准化至-1~+1的浮点数。并调整数据表形状(reshape)为模型输入参数的结构。

输入参数结构
(建议把源代码的若干个相关行分自然段,每个自然段添加一行中文注释。比如reshape的,astype的)

模型函数:

模型函数

模型训练部分代码(添加少量关键中文注释):

训练部分代码
这里保存了临时文件xxx_ctx.h5,为了训练中途意外停止后,重新训练时可以支持断点续练。

优化器使用RMSprop,损失函数使用mean_squared_error。

训练损失函数

训练时误差迅速下降,下降速度越来越慢,20轮训练后精度即已接近最终效果。这里显示了训练了120次后的结果:loss=0.0044.

训练过程误差

各位看官读到这里是不是脑海里已经有了智能车策马奔腾的画面了,并且迫不及待的想把训练好的模型部署到小车上了?
No No No,经常被生活打脸的小编告诉你这是完全不够的。为什么呢?很简单模型过拟合了。AI模型运行时会有误差,迟早导致出轨,那么有哪些误差呢:

模型计算的误差,逻辑回归引入的误差,无论训练多少遍一定会存在一定的误差

训练数据采集时的误差,前置电感和车身电感距离上的误差

累积误差,前两种误差会导致小车偏离轨道以至误差越来越大。积累到在训练数据里没有出现过的程度时,模型就不知该怎么办了,这是出轨的根源(说起来简单,小编其实被虐了很久才悟出来)。

知道了症结所在,就可以对症下药了:尽可能让训练数据里出现小车的各种回归正轨的模式。简单的说就是要引入从偏离轨道状态重返回轨道过程的纠正数据,我们通过两种办法获得纠正数据。

第1种方法:把小车电机配置成手动控制模式,但要保留转向控制功能和数据采集功能。把小车移动到偏离位置,手动推动小车,小车原有的控制算法会矫正方向使小车回到轨道上去。同时要抓取实时数据并保存。如下视频所示

手动控制模式采集数据

第2种方法:在用经典算法引导小车时,加入随机干扰,故意让小车偏离轨道一会,同时让控制算法短暂休眠,小车在此期间会出轨,待算法唤醒后赶紧再纠正回来,并且实时保存纠正的数据。如下视频所示

经典算法引导采集数据

总结一下,数据分三部分:

经典算法导航的正常数据。

手动偏移的纠正数据。

经典算法随机干扰的纠正数据。

把三个数据合成一套训练数据。特别注意第2种方法中可能会引入错误数据(小车过度偏离赛道,手动移动小车时小车与赛道平面角度过大或与水平面距离太远),实际操作过程中要小心。由于机器学习的不可解释特性,错误数据或不合适数据会导致不可预知的行为,所以整个过程可能需要多次尝试和调整。

模型部署

经过多轮的训练,我们得到最终的模型文件smartcar.h5。

那么怎么部署到小车上呢,这要借助“NNCU”这一套神器了。NNCU模型转换器可以点击这里从网盘下载,这里有个大礼包,里面有nnCU工具、教学视频、用户手册,还有一个MCU+AI的ppt。
通过转换器把模型转换成C文件。这样就可以很方便的集成到原有的工程中了,注意还需要集成一些依赖库和算法库,可以参考性能测试工程(nncie_stub.uvproj)。
从网盘中下载解压nncu_test_nighty.7z,运行“nncu_vbgui.bat”,选择模型文件,配置信息如下:

模型配置信息
这里我们使用14位来量化模型,对于NNCU工具,9-16位都会使用16位整数来封装。

16位量化和8位量化相比,以牺牲少量模型推理时间和加倍模型数据的代价,换来几乎无损的精度。
这里还有个重要的小建议:虽然使用16位整数来表达,但实际最好只使用其中的9-15位(未用的位会自动做有符号扩展),是为了防止模型运算期间的乘累加溢出。

注意输入数据移位指数7位,这意思是说数据里有7个二进制位用于表达分数(或者说是小数)部分。回想前文提到测试集和训练集中数据范围是-128+127,而模型训练时,模型处理数据范围是-1+1,所以量化数据里其实是放大到128倍了,也就是7个二进制分数位。

我们再看“输出后处理类型“。由于模型是做预测,后处理需要用户自己处理,不需要执行引擎后处理。
中间层、输出层分数位数:由于模型输出是-1~+1之间,10位分辨率也比较够用,这里占用量化总位数14位中的10位来表达分数。大家也可以试试其它的,比如9-13,一般影响极小。
点击”干活!”,会跳出后台转换脚本的命令窗口,稍候片刻会在nncu_pc目录下生成model1.nncu.c—模型执行文件。那么怎么使用以及模型量化后性能怎么样呢?

NNCU工具里提供了测试工程“test_mcu”,各位同学可以通过这个工程测试量化后的模型性能,也可以参考这个工程来进行模型移植工作。具体的操作,可以点击看这个视频(末尾部分),也可以看这篇微信文章"在MCU上实现AI深度学习,你想知道的都在这儿"以了解更多。

测试性能,首先需要制作测试数据集。我们把ad_test_dat.npy作为输入,把模型计算结果和pwm_test_label.npy值的平方差作为误差,计算平均差值来评估量化后的模型性能。

把训练集和测试集复制到”datasetssmartcar_ad”目录,命名如下:

存储训练集和测试集合的目录

点击工具右下角“制作测试数据”按钮。选择迷你数据集中smartcar_ad,点击”干活"。在目录nncu_pc下生成测试文件smartcar_ad.nctv.c。

生成测试文件
下一步是测试模型性能(参照帮助视频“nncu_使用入门.mp4”)。拷贝model1.nncu.c, smartcar_ad.nctv.c到目录test_mcuoardsevkmimxrt1060demo_apps ncie_stub中,覆盖原有文件:model.nncu.c,tv.nctv.c。

打开工程mdk ncie_stub.uvprojx,在helo_world.c中的测试函数CIETest,模型计算测试集求得平均差值。平均差值越小表示模型在测试集的拟合性越高。但注意这是没有累积误差情况下,实际上需要多加入回归正轨的数据,否则即使差值小也不能保证实际效果,只是模型过拟合,在测试集上表现的很好。

应用模型激素测试集合进行测试

CI_RunModelXIP_NoCopyOutput(pvModel, pImg + 8, (void**)&g_out);

是模型执行的函数调用,用法如下:

pvModel – 模型数据,在model1.nncu.c定义,包含了模型的信息和参数

pImg + 8 – x_text 也就是7个AD数值

g_out – 模型输出buffer,根据配置输出为16bit,带有分数位的数据。需要移位得到-128~+127的数值范围才能发送给舵机。

编译工程,通过JLink连接板子,并打开串口程序,接收串口的调试信息。开始debug模式,工程默认使用sram运行程序,等待测试程序执行。执行结束后,串口会输出执行结果:即平均差值,和平均执行时间。

小编训练的模型6000次平均差值是16,每次计算时间1.87dms——0.187ms。

o4YBAF_pktSAbcYgAACOxclUo0U798.png

串口输出测试结果

实战演习

经过模拟测试,模型性能符合预期,下一步就是把相关代码集成到电磁车系统中。首先集成nncie库nncie_imxrt10x0.lib,model.nncu.c,以及nncu_mcucmsis_nnSource中的CMSIS_NN相关代码(参照测试工程)。其次集成模型的调用方法:

o4YBAF_pkuGABtizAADaoN6bz3I138.png

模型调用方法
model1数组就是模型数据,ad_array是7个电感数据(如果12bit,需要移位到8bit),pwm是模型计算的转向值(范围-128+127)。请注意,制作训练数据时,为了方便训练计算,我们把转向值范围由真实值-420420压缩到了-128127,所以在控制舵机时,需要把计算所得的转向值放大到-420+420。

现在小伙伴可以在赛道上验证模型的实际性能了,可能第一次不会成功,需要多些耐心处理训练数据反复的重新训练,迭代调试了。

结果展示

这是小编训练的模型的实际运行情况(摘除了前置采集装置)

AI电磁车模实际运行情况

未来展望

以上是AI机器学习部署到电磁智能车的全过程,可以验证机器学习在电磁智能车上实施的可行性。
在这个过程中遇到很多问题,主要是处理分析训练数据,经过多次迭代训练才得到一个基本可靠的模型。
当然还存在一些有待改进地方:

小车目前还是匀速运动,没有速度变化,怎样设计更好的模型来引入速度参数?

数据获得方式是不是有更好的办法,通过对电磁轨道的模拟,来通过公式工具推导训练数据?

怎样可以引入更加丰富的赛道内容,比如交通引导线,指示灯,障碍物?等等。
编辑:hfy

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 神经网络
    +关注

    关注

    42

    文章

    4733

    浏览量

    100410
  • AI
    AI
    +关注

    关注

    87

    文章

    29740

    浏览量

    268041
收藏 人收藏

    评论

    相关推荐

    企业AI模型部署怎么做

    AI模型部署作为这一转型过程中的关键环节,其成功实施对于企业的长远发展至关重要。在此,AI部落小编为您介绍企业AI模型
    的头像 发表于 11-04 10:15 63次阅读

    RT-Thread AIOS,让小车更懂你!

    RT-ThreadAI团队经历对大量芯片厂商和下游应用业务公司的咨询和讨论,认为在可预见的未来,AI会产生一种端侧和云端混合部署的形态,即大规模、大参数模型运行在云端,如大语言模型,
    的头像 发表于 11-01 08:10 189次阅读
    <b class='flag-5'>RT</b>-Thread AIOS,让<b class='flag-5'>小车</b>更懂你!

    AGV读卡器在AGV自动搬运小车上应用方案

    AGV小车上的AGV读卡器通过读取地面轨道的RFID电子标签信息,做出相应的动作(如改变速度、选择轨道、定位和停车等)。在AGV小车经过站点A处时,AGV读卡器读取A处的电子标签ID号,AGV小车
    的头像 发表于 10-12 17:33 178次阅读
    AGV读卡器在AGV自动搬运<b class='flag-5'>小车上</b>应用方案

    混合部署 | 在RK3568上同时部署RT-Thread和Linux系统-迅为电子

    混合部署 | 在RK3568上同时部署RT-Thread和Linux系统-迅为电子
    的头像 发表于 09-06 15:32 321次阅读
    混合<b class='flag-5'>部署</b> | 在RK3568上同时<b class='flag-5'>部署</b><b class='flag-5'>RT</b>-Thread和Linux系统-迅为电子

    IBM Cloud将部署英特尔Gaudi 3 AI芯片

    近日,科技巨头IBM与英特尔宣布了一项重大合作计划,双方将共同在IBM Cloud平台上部署英特尔最新的Gaudi 3 AI芯片,预计该服务将于2025年初正式上线。此次合作标志着两家公司在推动AI技术创新与应用方面迈出了坚实的
    的头像 发表于 09-03 15:52 332次阅读

    利用恩智浦云实验室部署AI模型

    如今,人工智能(AI)非常火爆,这个风口该如何把握?作为一个电子工程师,和AI最主要的交集应该就是边缘计算了,具体来讲,就是在一些性能、功耗以及价格相对较低的嵌入式平台上部署和运行AI
    的头像 发表于 08-02 11:46 2639次阅读
    利用恩智浦云实验室<b class='flag-5'>部署</b><b class='flag-5'>AI</b>模型

    CubeIDE生成的代码框架会卡在MX_X_CUBE_AI_Process()函数中是怎么回事?

    当我将网络模型部署到STM32F407VGT6中时,CubeIDE生成的代码框架会卡在MX_X_CUBE_AI_Process()函数中是怎么回事?CUbeAI库的版本是9.0。期待您的回复,谢谢
    发表于 05-30 06:11

    6月6日杭州站RT-Thread线下workshop,探索RT-Thread混合部署新模式!

    6月6日下午我们将在杭州举办RT-Thread混合部署线下workshop,在瑞芯微RK3568平台上实现同时运行RT-Thread和linux,本次workshop邀请到RT-Thr
    的头像 发表于 05-28 08:35 380次阅读
    6月6日杭州站<b class='flag-5'>RT</b>-Thread线下workshop,探索<b class='flag-5'>RT</b>-Thread混合<b class='flag-5'>部署</b>新模式!

    基于stm32h743IIK在cubeai上部署keras模型,模型输出结果都是同一组概率数组,为什么?

    基于stm32h743IIK,在cubeai上部署keras模型,模型输出结果都是同一组概率数组,一点也搞不明白,看社区也有相同的问题,但没有解决方案
    发表于 05-20 08:18

    RT-Thread混合部署Workshop北京站来啦!

    4月25日,下午我们将在北京举办RT-Thread混合部署线下workshop,在瑞芯微RK3568平台上实现同时运行RT-Thread和linux,本次workshop邀请到RT-T
    的头像 发表于 04-19 08:34 381次阅读
    <b class='flag-5'>RT</b>-Thread混合<b class='flag-5'>部署</b>Workshop北京站来啦!

    4月25日北京站RT-Thread线下workshop,探索RT-Thread混合部署新模式

    4月25日,下午我们将在北京举办RT-Thread混合部署线下workshop,在瑞芯微RK3568平台上实现同时运行RT-Thread和linux,本次workshop邀请到RT-T
    的头像 发表于 04-16 08:35 377次阅读
    4月25日北京站<b class='flag-5'>RT</b>-Thread线下workshop,探索<b class='flag-5'>RT</b>-Thread混合<b class='flag-5'>部署</b>新模式

    4月10日深圳场RT-Thread线下workshop,探索RT-Thread混合部署新模式!

    4月10日我们将在深圳福田举办RT-Thread混合部署线下workshop,在瑞芯微RK3568平台上实现同时运行RT-Thread和linux,本次workshop邀请到RT-Th
    的头像 发表于 03-27 08:34 461次阅读
    4月10日深圳场<b class='flag-5'>RT</b>-Thread线下workshop,探索<b class='flag-5'>RT</b>-Thread混合<b class='flag-5'>部署</b>新模式!

    如何配置RT106x/RT107x从(非序列的)NAND启动的应用程序注释或示例?

    是否有关于如何配置 RT106x/RT107x 从(非序列的)NAND 启动的应用程序注释或示例? 我找到了一些信息, 但是还没有在一个地方找到所有的信息。 如果它也包含一个例子, 那将会是件好事。
    发表于 11-13 06:32

    基于OpenVINO C# API部署RT-DETR模型

    Python API 部署 RT-DETR 模型 | 开发者实战》和《基于 OpenVINO C++ API 部署 RT-DETR 模型 | 开发者实战》,在该文章中,我们基于 Op
    的头像 发表于 11-10 16:59 696次阅读
    基于OpenVINO C# API<b class='flag-5'>部署</b><b class='flag-5'>RT</b>-DETR模型

    如何在X86架构的嵌入式系统上部署掌纹识别算法

    安全性而备受关注。在这一背景下,越来越多的应用领域开始采用掌纹识别技术,包括金融、安全、物流和智能门禁等。本文将介绍如何在X86架构的嵌入式系统上部署一个开源的掌纹识别算法。
    的头像 发表于 11-10 16:53 1477次阅读
    如何在<b class='flag-5'>X</b>86架构的嵌入式系统<b class='flag-5'>上部署</b>掌纹识别算法