在日常生活中,带有人工智能的电器越来越常见了。似乎机器学习已经渗透到了生活的方方面面。Funpack第二季第1期就带来了这样一个支持机器学习的开发板。
硬件介绍:Syntiant TinyML Board:配备超低功耗 Syntiant ? NDP101神经决策处理器?,可以使语音和传感器应用程序分别在 140 和 100 微瓦以下运行,与基于 MCU 的传统 MCU 相比,吞吐量提高 20 倍,系统效率提高 200 倍。Syntiant TinyML 板的尺寸为 24 毫米 x 28 毫米,是一个小型的独立系统,通过微型 USB 连接通过 Edge Impulse 轻松下载经过训练的模型,而无需任何专用硬件。
任务选择:本期活动有两个任务,一个是使用板载的数字麦克风做语音识别,另一个是自由发挥。我选择任务二。使用板子上的运动传感器来识别动作。板子上装有一颗三轴角速度、三轴加速度传感器。使用这个传感器来感知动作信息。我选择了三种动作:摇头——对应标签“NO”,代表着较为剧烈的快速地左右大幅晃动。点头——对应标签“YES”,缓慢地大幅地晃动。晃头——对应标签“MAYBE”,就是那种印度式的晃动脑袋,快速地轻微的晃动,表示模棱两可。“YES”标签对应亮绿灯;“NO”对应亮红灯;“MAYBE”对应亮蓝灯。
实现过程:
1、准备工作。官网对imu提供的支持出来的比较晚,在网页上可以学习到如何使用imu来收集数据。首先需要准备一张SD卡,使用运动传感器收集数据需要用到SD卡(这个开发板非常挑SD卡,测试了4张卡,仅仅一张闪迪的16G卡可以使用)。SD卡预先格式化(FAT32格式)。从https://docs.edgeimpulse.com/docs/development-platforms/officially-supported-mcu-targets/syntiant-tinyml-board页面下载IMU firmware固件。将固件解压后,运行文件夹中的批处理文件,即可将固件写入开发板。(这里烧写固件时最好插上SD卡,感觉不插SD卡,后边运动数据无法收集,但自己不确定是否为必须)。
A new release of Arduino CLI is available: 0.19.2 → 0.23.0
https://arduino.github.io/arduino-cli/latest/installation/#latest-packages
You're using an untested version of Arduino CLI, this might cause issues (found: 0.19.2, expected: 0.13.x
Finding Arduino SAMD core v1.8.9...
arduino:samd 1.8.9 1.8.13 Arduino SAMD Boards (32-bits ARM Cortex-M0+)
Finding Arduino SAMD core OK
Finding Arduino MKRZero...
Finding Arduino MKRZero OK at COM19
Flashing Arduino firmware...
Atmel SMART device 0x10010005 found
Device : ATSAMD21G18A
Chip ID : 10010005
Version : v2.0 [Arduino:XYZ] Apr 11 2019 13:09:53
Address : 8192
Pages : 3968
Page Size : 64 bytes
Total Size : 248KB
Planes : 1
Lock Regions : 16
Locked : none
Security : false
Boot Flash : true
BOD : true
BOR : true
Arduino : FAST_CHIP_ERASE
Arduino : FAST_MULTI_PAGE_WRITE
Arduino : CAN_CHECKSUM_MEMORY_BUFFER
Erase flash
done in 0.831 seconds
Write 106868 bytes to flash (1670 pages)
[==============================] 100% (1670/1670 pages)
done in 0.783 seconds
Verify 106868 bytes of flash with checksum.
Verify successful
done in 0.095 seconds
CPU reset.
Flashed your Arduino MKRZero development board. Board restarting...
等待 0 秒,按 CTRL+C 退出 ...
Writing NN model to flash...
Program : 100% [============================================================]
sum = 38518 (0x9676) 256260 bytes written in 2.479 sec, 826978 bits/s
Read : 100% [============================================================]
sum = 38518 (0x9676) 256260 bytes read in 2.034 sec, 1007905 bits/s
Writing NN model OK
Press reset button to start the application
请按任意键继续. . .
2、收集数据。登录EDGE IMPULSE网站,创建新的项目。电脑接好插了SD卡的开发板。点击Data acquistition进入收集数据页面。
点击上边提示栏里的Show options
选择从电脑收集数据。
这里我们是需要收集动作信息,所以选择“Collecting motion”。
在这个页面设置标签、设置动作时长。我这里选择的时长为2秒。点击“Startrecording”就可以收集动作信息了。用手晃动开发板来模拟三种不同的动作。这里会遇到几个问题:1、提示没有找到SD卡,这就是开发板挑SD卡的情况了,解决方法就是换SD卡。2、收集到的动作信息是一条直线。不知道是什么原因,收集不到动作传感器的数据。我的经验是,烧写固件时插上SD卡,烧写完成后断电重启开发板。多试几次貌似可以解决。3、收集动作数据时显示已上传,但是数据集列表中没有增加样本数据。这个基本是网络原因了。没啥好办法,科学上网或者多试几次。
3、训练数据。收集到一定数量的动作数据后,选择页面上“impulse design”下的“Create impulse”。基本使用的都是默认值,数据选择6轴的全部数据,时长用的是1800ms,滑动窗口使用了80ms。神经网络使用NN。
然后在“Syntiant IMU”页面可以查看各个动作的波形图,这里需要留意,不要点选“Scale 16 bits to 8 bits”,若是点选这个,应该就会把数据映射到【-1,1】里边,最后结果变得很差,所以不要选中这个。
配置完参数后,就是对数据进行训练。训练结果还不错,MAYBE和NO能够达到100%,YES略差一些,只有80%。
4、模型部署。训练好模型后,就需要再开发板上部署自己的模型了。点击“Deployment”,这里提供了三种方法部署。这里我选择“Syntiant NDP101 library”,生成模型对应的库文件。先点击“Find posterior parameters”,选中三个标签,最后生成模型对应的库文件。
库文件下载后,就可以在arduino里进行自己的编程了。从github下载工程项目,使用这个工程来进行修改。将下载的库文件下model-parameters的三个头文件,覆盖工程文件下src下的model-parameters里的文件。然后修改model_variables.h文件(不做修改编译会报错)。收集完训练数据,开发板里的SD卡就可以拔掉了,后边使用过程中不再需要使用SD卡。
/* Generated by Edge Impulse
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef _EI_CLASSIFIER_MODEL_VARIABLES_H_
#define _EI_CLASSIFIER_MODEL_VARIABLES_H_
#include <stdint.h>
#include "model_metadata.h"
//#include "edge-impulse-sdk/classifier/ei_model_types.h"
const char* ei_classifier_inferencing_categories[] = { "MAYBE", "NO", "YES" };
uint8_t ei_dsp_config_3_axes[] = { 0, 1, 2, 3, 4, 5 };
const uint32_t ei_dsp_config_3_axes_size = 6;
ei_dsp_config_imu_syntiant_t ei_dsp_config_3 = {
1,
6,
false
};
//const ei_model_performance_calibration_t ei_calibration = {
// 1, /* integer version number */
// (int32_t)(EI_CLASSIFIER_RAW_SAMPLE_COUNT / ((EI_CLASSIFIER_FREQUENCY > 0) ? EI_CLASSIFIER_FREQUENCY : 1)) * 1000, /* Model window */
// 0.8f, /* Default threshold */
// (int32_t)(EI_CLASSIFIER_RAW_SAMPLE_COUNT / ((EI_CLASSIFIER_FREQUENCY > 0) ? EI_CLASSIFIER_FREQUENCY : 1)) * 500, /* Half of model window */
// 0 /* Don't use flags */
//};
#endif // _EI_CLASSIFIER_MODEL_METADATA_H_
使用arduino对工程文件进行编译,开发板选择“Arduino MKRZERO”,通过串口烧写进开发板。然后就可以通过串口和LED灯观察程序运行结果了。
5、存在的问题。整个项目做下来,总还是剩一些问题尚未解决。
第一个问题是:做数据收集时无法收集到数据。在收集数据页面,显示成功上传数据后,收集到的数据是一条直线,无法收集到运动数据,同样的方法,多次烧写,有时又能正常收集数据,没能找到原因。
第二个问题是:开发板有卡死情况。这样的情况出现在我办公室得台式机上。通过Arduino编译烧写后,通过串口观察数据,发现运行一段时间后会出现三个标签识别均为0,然后开发板就卡死,不再有数据返回。其它电脑烧写就不会有这样的情况。
第三个问题:开发板总是在不停地识别动作,很多时候不是自己想要的结果。没有提供每个标签的概率值供筛选。
心得体会:
非常喜欢这个能实现机器学习的开发板,感谢funpack组织的活动。Syntiant+ TinyML使得开发板可玩性超强,期待着学习大家的作品。