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

关键词人工智能AI电磁智能车智能车竞赛机器学习

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

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

01 先期准备


1.硬件条件

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

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

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

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

2.软件环境

  • Python:3.7.3
  • Keras:2.2.4
  • TensorFlow:1.13.1

02 模型设计


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

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

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

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

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

03 采集数据,训练模型


1.数据采集和处理

  众所周知训练数据是机器学习的重中之重,没有完备的数据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值做一个简单滤波。以下是我们使用的滤波算法仅供参考。

简单的滤波算法

2.模型训练

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

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

  模型函数:

模型函数

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

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

  优化器使用RMSprop,损失函数使用mean_squared_error。
![训练损失函数](https://img-blog.csdnimg.cn/20200220232541288.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3podW9xaW5nam9raW5nOTcyOTg=,size_16,color_FFFFFF,t_70#pic_cente r=560x)

训练损失函数

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

训练过程误差

  各位看官读到这里是不是脑海里已经有了智能车策马奔腾的画面了,并且迫不及待的想把训练好的模型部署到小车上了?
  No No No,经常被生活打脸的小编告诉你这是完全不够的。为什么呢?很简单模型过拟合了。AI模型运行时会有误差,迟早导致出轨,那么有哪些误差呢:
  1. 模型计算的误差,逻辑回归引入的误差,无论训练多少遍一定会存在一定的误差
  2. 训练数据采集时的误差,前置电感和车身电感距离上的误差
  3. 累积误差,前两种误差会导致小车偏离轨道以至误差越来越大。积累到在训练数据里没有出现过的程度时,模型就不知该怎么办了,这是出轨的根源(说起来简单,小编其实被虐了很久才悟出来)。

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

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

手动控制模式采集数据

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

经典算法引导采集数据

  总结一下,数据分三部分:
  1. 经典算法导航的正常数据。
  2. 手动偏移的纠正数据。
  3. 经典算法随机干扰的纠正数据。

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

3.模型部署

  经过多轮的训练,我们得到最终的模型文件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值的平方差作为误差,计算平均差值来评估量化后的模型性能。

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

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

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

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

  打开工程mdk\nncie_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。

串口输出测试结果

03 实战演习


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

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

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

04 结果展示


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

AI电磁车模实际运行情况

05 未来展望


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

  • 小车目前还是匀速运动,没有速度变化,怎样设计更好的模型来引入速度参数?
  • 数据获得方式是不是有更好的办法,通过对电磁轨道的模拟,来通过公式工具推导训练数据?
  • 怎样可以引入更加丰富的赛道内容,比如交通引导线,指示灯,障碍物?等等。

  相信同学们还可以提出更多好的想法,同学们和赛事参与者可以开动脑筋,让AI机器学习的潜力能尽情地发挥!

AI机器学习实战の电磁智能车篇相关推荐

  1. 时雨月五| AI机器学习实战の电磁导航智能车中神经网络应用的问题与思考

    "不愤不启,不悱不发.举一隅不以三隅反,则不复也". – <论语·述而> 再次将论语中的这句"不愤不启,不悱不发"引用在这里,说明学生的学习的活动部 ...

  2. 基于i.MX RT电磁智能车AI算法的一些讨论

      该文发布后得到了热烈的反响,也有学生提出了一些问题,典型的是适应性问题,如下:   也另外有专家针对这些问题提出了自己的看法:   在此,我想分享一下我们在进行相应的测试和实验过程中,所遇到的问题 ...

  3. 基于RT106x电磁智能车AI算法

      今天,来自NXP公司的宋岩和张岩向我展示和讨论了他们使用部署在智能车单片机中上的人工神经网络控制电磁车模运行的实验情况情况.下面的视频中,车模的方向控制是由单片机中的神经网络模型给出了.车模运行速 ...

  4. 第八届CUIT电磁智能车比赛参赛学习总结 Part1:工字电感+LMV358型电磁杆

    部分资料和图示来源网络,如有侵权请联系删稿 Part1:认识电感 工字电感的组成:工字电感线圈一般由工字形磁芯骨架跟漆包铜线及一些辅料组成的电磁感应元件,它主要是在工字骨架的槽内绕上线圈,线圈的二个头 ...

  5. 机器学习实战教程汇总(十三篇)

    机器学习实战教程(13篇) 这些网址非常适合想学习机器学习,却苦于没有项目(尤其缺少数据)的人.无意中看到,给自己做一个记录. 机器学习实战教程(一):K-近邻算法(史诗级干货长文)https://c ...

  6. 机器学习实战2(决策树篇)

    目录 1.决策树 2.决策树的构造 3.决策树的可视化 4.测试和存储决策树 1.决策树 你是否玩过二十个问题的游戏,游戏的规则很简单:参与游戏的一方在脑海里想某个事物,其他参与者向他提问题,只允许提 ...

  7. 《机器学习实战》——线性回归提高篇之乐高玩具套件二手价预测

    一.前言 本篇文章讲解线性回归的缩减方法,岭回归以及逐步线性回归,同时熟悉sklearn的岭回归使用方法,对乐高玩具套件的二手价格做出预测. 二.岭回归 如果数据的特征比样本点还多应该怎么办?很显然, ...

  8. 机器学习实战应用案例100篇(二)-蚁狮优化算法从原理到实战应用案例

    蚁狮优化算法(原理) 1 简介 蚁狮(Antlions,蚁蛉)属于蚁蛉科和神经翅目(网翅昆虫).蚁狮的生命周期包括两个主要阶段:幼虫和成虫. 自然的总寿命可达3年,主要发生在幼虫(成虫期只有3 - 5 ...

  9. 机器学习实战应用案例100篇(十四)-飞蛾扑火优化算法从原理到实战应用案例

    飞蛾扑火优化算法(原理) 1 算法简介 飞蛾是一种奇特的昆虫,与蝴蝶家族非常相似.基本上,自然界有超过16万种不同种类的这种昆虫.它们一生中有两个主要的里程碑:幼虫和成虫.幼虫在茧中变成蛾. 关于飞蛾 ...

最新文章

  1. 射频领域中交调和互调的区别
  2. 重构碎片化知识_知识碎片化时代,如何妙用思维导图,提高你的学习效率(含福利)...
  3. 【转载保存】Java丨jsoup网络爬虫登录得到cookie并带上cookie访问
  4. 妙味css3课程---1-1、css中自定义属性可以用属性选择器么
  5. centos oracle sqlplus,centos 下oracle sqlplus乱码问题解决
  6. mysql 事务 异常_mysql事务级别以及相应的异常现象
  7. Java Timetask 无缘无故停止
  8. 桥牌笔记:挤牌的条件之一,调整赢墩到只差一墩
  9. matlab分析xml文件_修改Java中的XML文件(DOM分析器)
  10. hiho一下 第五十周 (求欧拉路径)
  11. PHP5应用实例详解
  12. Markdown 表格
  13. 开发前奏曲之添加Android SDK平台工具
  14. Linux下Mongodb安装和启动配置
  15. 利用ES4封装Windows10
  16. 使用usb to ttl串口下载器破解移动电视盒子(CM201-2)
  17. [源码分析]go-graceful如何shutdown gracefully
  18. oa处理会签流程图_深入剖析OA办公系统的流程管理方案
  19. Python自动化--1.Python环境安装-linux
  20. MySQL数据库——MySQL数据表添加字段(三种方式)

热门文章

  1. django源码分析 LazySetting对象
  2. Java反射实践:从反射中理解class
  3. 漫画:你会感觉容器使用起来很痛苦吗?
  4. 从封装函数到实现简易版自用jQuery (一)
  5. SqlSugar常用查询实例-拉姆达表达式
  6. Storm集群安装部署步骤【详细版】
  7. Handle table中CAS操作与A-B-A Problem解析
  8. C语言scanf fgets,C语言中输入函数(scanf()、fgets()和gets())的区别详解
  9. intel的linux证书过期,rhce证书过期了可以怎么办
  10. 霍夫变换MATLAB怎么实现,做过Matlab关于霍夫变换检测圆的高手请进