在 Arduino 上使用机器学习
客座博文 / Sandeep Mistry & Dominic Pajak,来自 Arduino 团队
Reviewed by GDE 胡旭华
示例 1:运行预训练的 micro_speech 推理示例
Arduino 是一款便捷灵活、易用易学的开源电子设计原型平台。为了让 Arduino 可以肩负起让“任何人均可轻松使用机器学习”的使命,我们已经和 TensorFlow Lite 团队开展了数月的合作。现在我们很高兴能向大家展示我们的合作成果:将 TensorFlow Lite Micro 与 Arduino Nano 33 BLE Sense 结合使用。在本文中,我们将为您介绍多个 TensorFlow Lite Micro 示例,并展示如何安装与运行 ,这些示例均在 Arduino 库管理器中提供。
我们的第一个教程是如何在 Arduino 开发板上安装一个神经网络,并识别简单语音指令。
示例 2:训练您自己的手势分类模型
如果您之前使用过 Arduino,可能只需几小时就能将这些教程中的知识学以致用。如果您刚开始接触微控制器,那么需要的时间可能久一点。
我们很高兴能向与大家分享这些入门示例和教程,期待您能利用这些资源做出更丰富多彩的 demo。那么,现在我们开始吧!
注意:以下项目基于 TensorFlow Lite for Microcontrollers,目前已在 TensorFlow 代码库中发布实验性版本。这一新兴领域仍然处于发展初期,欢迎加入与分享您的实例!
微控制器和 TinyML
微控制器(Microcontrollers,如在 Arduino 开发板上使用的微控制器)是低成本、单芯片的独立计算机系统。这些微控制器隐藏在无数日常产品中,是嵌入在如穿戴式设备、无人机、3D 打印机、玩具、电饭锅、智能插座、电动踏板车、洗衣机等产品的内置计算机。将这些设备相互连接也是物联网发展的趋势。
Arduino 是一个专注于让每个人都能使用微控制器进行应用开发的开源平台和社区。我们在本教程中使用的开发板配置为运行频率 64 MHz,1MB 闪存和 256 KB RAM 的 Arm Cortex-M4 微控制器。与云平台、PC 或移动端设备相比,这个配置可能很微不足道,但如果以微控制器的标准来衡量,是一款很正常的微控制器。
Arduino Nano 33 BLE Sense 开发板比一片口香糖还小
功能 - 智能设备希望能够在本地快速运行(独立于互联网); 成本 - 借助简单、低成本的硬件实现这一目的; 隐私 - 无需对外分享传感器数据; 效率 - 设备拥有更小巧的外形,可实现节约能源或更长的使用时间。
机器学习可以让没有嵌入式研发背景的程序员也能使用微控制器
从机器学习方面而言,您可以借助各类技术将神经网络模型应用于内存受限的设备(如微控制器)。其中一个重要步骤是权重参数的量化从浮点数转化为 8 位整数。这还可以加快推理的计算速度,更适用于低主频设备。
TinyML 是一个新兴领域,目前仍有很多事情亟待解决,但可喜的是,该领域尚有广阔的应用空间有待我们去探索。数十亿微控制器与渗透在生活方方面面的各类传感器相结合,未来会激发更多富有创造力的 Tiny ML 应用。
准备材料
一块 Arduino Nano 33 BLE Sense 开发板; 一根连接 Arduino 开发板和您的台式电脑的 Micro USB 数据线; 如果要在您的开发板上编程,您可以使用 Arduino 网页编辑器或安装 Arduino IDE。我们将在后文为您介绍如何做好这些准备工作。
语音 - 数字麦克风 移动 - 9 轴 IMU(加速度计、陀螺仪、磁力计) 环境 - 温度、湿度和压力 光线 - 亮度、颜色和接近传感器
与经典的 Arduino Uno 不同,Nano 33 BLE 将微控制器与板载传感器结合在一起,这意味着您在无需额外配置其他硬件或接线的情况下,便可处理许多用例。此开发板的外形也非常小巧,也可应用于穿戴式设备等终端应用中。顾名思义,此款 Arduino 支持蓝牙 LE 连接,因此您可以发送数据(或推理结果)到笔记本电脑、移动应用或其他 BLE 开发板和外设。
提示:U 盘上的传感器
通过 USB 连接 BLE Sense 开发板可以轻松采集数据并向单板计算机添加多个传感器,无需额外配置接线或硬件 — 添加到 Raspberry Pi 就是一个很好的例子。
TensorFlow Lite for Microcontrollers 示例
micro_speech - 使用板载麦克风的语音识别 magic_wand - 使用板载 IMU 的手势识别 person_detection - 使用外部 ArduCam 相机的人类检测
如需了解更多相关的信息,您可以在 TensorFlow 代码库中查看这些示例的源代码。这些示例使用的模型都是之前已经训练好的。接下来的教程将介绍如何在 Arduino 上部署并运行这些示例。至于如何训练这些模型,我们将在下一节进行探讨。
如何使用 Arduino Create 网页编辑器运行示例
使用 USB 数据线将您的 Arduino Nano 33 BLE Sense 连接到台式电脑后,您将可以使用 Arduino Create 网页编辑器在开发板上编译并运行以下 TensorFlow 示例:
从 Arduino_TensorFlowLite 库编译示例
重点介绍语音识别示例:micro_speech
使用 Arduino 开发板的最初步骤之一是让 LED 闪烁。此处,我们将采取稍微不同的方式,通过使用 TensorFlow Lite Micro 识别语音关键字。其拥有一个由“yes”和“no”组成的简单词汇表。切记,此模型仅使用 256KB RAM,并在本地微控制器上运行,因此不要期待与商业级别“语音助手”相同的准确性。模型没有连接到互联网连接,并且本地可用 RAM 相差了近 2000 倍。
请注意,此开发板也可以使用电池供电。Arduino 可以连接到电机、执行器等设备,因此适用于语音控制项目。
运行 micro_speech 示例
如何使用 Arduino IDE 运行示例
或许,您也可以尝试使用 Arduino IDE 运行同样的推理示例。
首先,请按照下一节 “设置 Arduino IDE” 内容的步骤进行操作。
在 Arduino IDE 中,您可以在 Arduino IDE 中依次访问 File > Examples > Arduino_TensorFlowLite 菜单,以查看可用示例。
选择一个示例,然后它的例程会自动打开。为了在板子上编译、上传和运行这个示例,请点击箭头图标:
对于偏好使用命令行的高级用户,您还可以使用 arduino-cli。
为 Arduino 训练一个的 TensorFlow Lite Micro 模型
Arduino BLE 33 Nano Sense 上的手势分类,输出为 Emojis
然后,我们将通过机器学习让 Arduino 开发板能识别手势。我们将从 Arduino Nano 33 BLE Sense 开发板采集运动数据,将其导入至 TensorFlow 中以训练模型,并将生成的分类器部署到开发板上。
此教程的想法以 Charlie Gerard 出色的《使用 Arduino 与 Tensorflow.js 玩街头拳击游戏》 (Play Street Fighter with body movements using Arduino and Tensorflow.js) 一文为基础。在 Chalie 的示例中,开发板将所有传感器数据流从 Arduino 传输到另一台电脑,并在这台电脑上使用 Tensorflow.js 执行手势分类。
我们的示例更进一步,利用 “TinyML 化”在 Arduino 开发板上执行手势分类。由于我们使用的 Arduino Nano 33 BLE Sense 开发板拥有更强大的 Arm Cortex-M4 处理器和板载 IMU,因此可以轻松实现上述过程。
下方的教程已经过我们的调整,因此不再需要额外硬件,当检测到开发板移动时便开始采样。在原始版本的教程中,需要添加一个电路板和一个硬件按钮,通过按下按钮来触发采样。如果您想添加一些硬件,可以改为按照此原始版本进行操作。
设置 Arduino IDE
为了将推理模型配置到到您的开发板中,并从开发板中下载后面所需的训练数据,请按照以下步骤设置 Arduino IDE 应用。因为我们将需要在 Arduino IDE 中下载并安装特定开发板和库,本方法采用的步骤比使用 Arduino Create 网页编辑器要多一些。
从 https://arduino.cc/downloads 下载并安装 Arduino IDE 打开您刚才安装的 Arduino 应用 在 Arduino IDE 菜单中,依次选择 Tools > Board > Boards Manager… 搜索“Nano BLE”,并点击“Install” 安装过程需要几分钟时间 安装完成后,请关闭 “Boards Manager” 窗口
现在,依次点击库管理器:Tools > Manage Libraries… 搜索并安装 Arduino_TensorFlowLite 库 接下来搜索并安装 Arduino_LSM9DS1 库:
最后,用 Micro USB 数据线连接开发板和您的计算机 选择开发板:Tools > Board > Arduino Nano 33 BLE 选择端口:Tools > Port > COM5 (Arduino Nano 33 BLE) 请注意,您的计算机上的实际端口名称可能有所不同
如需帮助,请参阅 Arduino 网站上更详细的入门指南和故障排除指南。
收集 Arduino 传感器的流数据
首先,我们需要采集一些训练数据。您可使用之前连接开发板与电脑用的数据线,从 Arduino 开发板采集传感器数据日志。
Arduino 开发板运行小型应用(也称为“例程,sketches”)时,这些应用通过 .ino 格式的 Arduino 源代码进行编译,并使用 Arduino IDE 或 Arduino Create 编程到开发板上。
监控开发板的加速度计和陀螺仪 在检测到开发板的显著线性加速时触发采样窗口 当达到 119Hz 时采样一秒,并通过 USB 输出 CSV 格式的数据 循环,继续监控下个手势
选择读取开发板上哪些传感器的数据、使用什么样的采样频率、设置怎样的触发阈值,以及将传感器数据流以 CSV、JSON、二进制,还是其他格式输出,这些全都可以在 Arduino 运行的例程中进行自定义。您还可以设置数据输出到日志前对设备执行信号预处理和过滤的范围,我们将在另一篇博客中介绍相关内容。就本节内容而言,您可以直接上传此例程,并开始采样。
下载 IMU_Capture.ino 并在 Arduino IDE 中将其打开 对其进行编译,并依次点击 “Sketch” > “Upload”,将其上传到开发板
实时显示 Arduino 开发板的传感器数据日志
完成上述步骤后,我们现在可以显示来自开发板的数据。我们还没有开始采集数据,此步骤只是让您了解传感器数据捕获的触发方式,以及采样窗口的持续时间。这将对采集训练样本很有帮助。在 Arduino IDE 中,依次点击 Tools > Serial Plotter,以打开 Serial Plotter 如果返回错误,则表示开发板不可用,请重新选择端口: Tools > Port > 端口名称 (Arduino Nano 33 BLE) 拿起开发板,练习 “击拳” 和 “弯曲肘部” 的动作 您将了解采样窗口仅持续一秒,然后等待下一个手势 您将看到传感器数据采集的实时图表(参见下方 GIF)
Arduino IDE Serial Plotter 将显示您开发板输出的 CSV 数据的实时图表
操作完成后,请务必关闭 Serial Plotter 窗口,此步骤很重要,否则下一步将无法进行。
采集手势训练数据
如要将数据采集为 CSV 日志以上传到 TensorFlow,您可以依次点击 Arduino IDE > Tools > Serial Monitor,以查看数据并将其导出到您的台式电脑:按顶部的白色小按钮,重置开发板 单手拿起开发板(之后再拿起会触发采样) 在 Arduino IDE 中,打开 Serial Monitor :Tools > Serial Monitor 如果返回错误,则表示开发板不可用,重新选择端口: Tools > Port > 端口名称 (Arduino Nano 33 BLE) 将开发板拿在手中做一个“击打”手势 确保出拳手势要快,以便触发采集 缓慢恢复到自然姿势,以免再次触发采集 做手势时请务必小心! 重复之前的手势采集步骤 10 次以收集更多数据 从串口控制台 (Serial Console) 中将数据复制粘贴到名为 punch.csv 的新文本文件 清空控制台输出窗口,并重复上述所有步骤,这次做一个“弯曲肘部”手势,将数据粘贴到名为 flex.csv 的文件中 快速做出向内弯曲肘部手势,以便触发采集,每次恢复自然姿势时要缓慢
请注意,您的两个 csv 文件的首行应当包含以下字段:aX、aY、aZ、gX、gY、gZ
Linux 提示:如果您愿意,可以通过命令行将传感器日志从 Arduino 直接输出为 .csv 文件。在 Serial Plotter/Serial Monitor 窗口关闭时,请使用以下命令:
$ cat /dev/cu.usbmodem[nnnnn] > sensorlog.csv
在 TensorFlow 中训练
我们将通过 Google Colab,使用我们在上一部分从 Arduino 开发板收集的数据训练我们的机器学习模型。Colab 提供 Jupyter 笔记本,可让我们在网络浏览器中运行自己的 TensorFlow 训练。
Arduino 手势识别训练 Colab
设置 Python 环境 上传 punch.csv 和 flex.csv 数据 解析并准备数据 构建并训练模型 将经过训练的模型转换为 TensorFlow Lite 将模型在 Arduino 头文件中编码
Colab 的最后一步是生成 model.h 文件以便下载,并将在下节中将其添加到我们的 Arduino IDE 手势分类器项目中:
我们来在 Colab 中打开上述笔记本,并在单元格 arduino_tinyml_workshop.ipynb 中运行一系列步骤。
对 IMU 数据进行分类
在 Arduino IDE 中打开 IMU_Classifier.ino 在 IDE 中创建一个新选项卡。并将其命名为 model.h
打开 model.h 选项卡,并将您从 Colab 下载版本的内容贴上去 上传例程,点击:Sketch> Upload 打开 Serial Monitor:Tools > Serial Monitor 做一些手势 每个手势的置信度将在 Serial Monitor 中显示(0 = 低置信度,1 = 高置信度)
恭喜,您已完成在 Arduino 上的首个机器学习应用!
想获得更多乐趣?您可使用 Emoji_Button.ino 示例创建 USB 键盘,在 Linux 和 macOS 中输出表情符号字符。尝试将 Emoji_Button.ino 示例与 IMU_Classifier.ino 例程相结合,创建手势控制的表情符号键盘 👊。
结论
很高兴能与您一起分享这些内容,但我们仍需深入学习和探索 Tiny ML。我们希望本文能为您提供一些灵感,抛砖引玉,启发更多可能性,让您开始将其应用到您自己的项目中。请务必与我们和 Arduino 社区分享您的构建成果。
如需全面了解本文中介绍的 TinyML 和示例应用的背景信息,我们推荐您阅读 Pete Warden 和 Daniel Situnayake 的 O'Reilly 新作TinyML:Machine Learning with TensorFlow on Arduino and Ultra-Low Power Microcontrollers。
如果您想详细了解 本文提及 的相关内容,请参阅以下文档。这些文档深入探讨了这篇文章中提及的许多主题:
Arduino
https://www.arduino.ccArduino Nano 33 BLE Sense
https://store.arduino.cc/nano-33-ble-senseTensorFlow Lite Micro
https://www.tensorflow.org/lite/microcontrollers/overviewArduino 库管理器
https://www.arduino.cc/en/guide/libraries#toc1发布
https://github.com/arduino/ArduinoTensorFlowLiteTutorials/tree/master/GestureToEmoji每个人/Arduino 社区
https://create.arduino.cc/projecthub权重参数的量化
https://petewarden.com/2016/05/03/how-to-quantize-neural-networks-with-tensorflow/Arduino 网页编辑器
https://create.arduino.cc/editorArduino IDE
https://www.arduino.cc/en/main/softwareTensorFlow 代码库
https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/experimental/microarduino-cli
https://github.com/arduino/arduino-cli#arduino-cli使用 Arduino 与 Tensorflow.js 玩街头拳击游戏
https://medium.com/@devdevcharlie/play-street-fighter-with-body-movements-using-arduino-and-tensorflow-js-6b0e4734e118原始版本
https://github.com/sandeepmistry/aimldevfest-workshop-2019入门指南
https://www.arduino.cc/en/Guide/NANO33BLESense故障排除
https://www.arduino.cc/en/Guide/TroubleshootingIMU_Classifier.ino
https://github.com/arduino/ArduinoTensorFlowLiteTutorials/blob/master/GestureToEmoji/ArduinoSketches/IMU_Capture/Google Colab
https://colab.research.google.com/arduino_tinyml_workshop.ipynb
https://github.com/arduino/ArduinoTensorFlowLiteTutorials/blob/master/GestureToEmoji/arduino_tinyml_workshop.ipynbIMU_Capture.ino
https://github.com/arduino/ArduinoTensorFlowLiteTutorials/blob/master/GestureToEmoji/ArduinoSketches/IMU_Classifier/IMU_Classifier.inoEmoji_Button.ino
https://github.com/arduino/ArduinoTensorFlowLiteTutorials/blob/master/GestureToEmoji/ArduinoSketches/Emoji_Button/Emoji_Button.ino