2. TinyML基础
TinyML 的核心挑战在于:如何在功耗仅为毫瓦级、内存以 KB 计、主频不过百 MHz 的微控制器(MCU)上,运行原本为服务器 GPU 设计的机器学习推理任务。理解这一层基础,是后续构建异常告警闭环的起点。本章将拆解微控制器上机器学习的运行原理、资源约束边界,并深入对比 Arduino Nano 33 BLE Sense 与 ESP32 这两类典型平台的工程适配性。
2.1 微控制器上机器学习的核心原理
与云端训练不同,MCU 上的机器学习几乎只做推理(Inference),即使用预先训练好的模型权重,对传感器采集的数据进行前向计算。训练过程在 PC 或服务器上完成,通过 TensorFlow 或 PyTorch 训练出模型后,经过剪枝(Pruning)、量化(Quantization)和算子融合(Operator Fusion),最终转换为适合 MCU 的格式(如 TensorFlow Lite Micro 的 .tflite 文件)。推理时,模型被加载到 Flash 中,输入数据通过 DMA 或中断方式进入 RAM,逐层执行卷积、池化、全连接等运算。
关键原理在于静态图执行:模型结构在编译期已确定,运行时不需要动态分配内存或解析复杂的数据流图。TFLite Micro 的解释器会预先规划好每一层的张量内存地址,避免频繁的 malloc/free 操作。这种设计使得推理过程具有确定性的时间开销和内存占用,非常适合实时性要求高的异常检测场景。
2.2 资源约束的量化分析与判断方法
在开始任何 TinyML 项目前,必须对目标硬件的资源边界进行量化评估。以下表格总结了典型 MCU 的资源约束及对应的设计策略:
| 资源类型 | 典型范围 | 约束影响 | 应对策略 |
|---|---|---|---|
| Flash 存储 | 256 KB - 4 MB | 模型权重 + 程序代码的总容量上限 | 使用 int8 量化,模型通常控制在 50-200 KB |
| SRAM | 32 KB - 512 KB | 推理时的中间张量、输入输出缓冲区 | 采用内存复用技术,避免大尺寸特征图 |
| CPU 主频 | 48 MHz - 240 MHz | 单次推理延迟,影响实时性 | 使用 CMSIS-NN 或硬件加速指令 |
| 功耗预算 | 10 mW - 100 mW | 电池供电场景下的续航时间 | 采用事件驱动采样,空闲时进入 deep sleep |
| 外设接口 | I2C / SPI / UART / GPIO | 传感器数据采集速率与精度 | 使用 DMA 传输,减少 CPU 中断负载 |
判断方法:在项目初期,建议先使用 tflite-micro 的 benchmark 工具在目标硬件上运行一个简单的测试模型,测量实际推理时间和峰值内存。如果推理时间超过采样周期的 50%,则需要考虑减小模型输入尺寸、减少层数或使用更激进的量化策略。例如,一个 128 点的 FFT 特征提取需要约 5 ms,而一个 10 层的 CNN 推理可能需要 80-150 ms,此时应优先优化模型结构而非提升主频。
2.3 典型硬件平台对比:Arduino Nano 33 BLE Sense 与 ESP32
这两款平台是 TinyML 入门最常用的选择,但它们的定位有明显差异。Arduino Nano 33 BLE Sense 基于 Nordic nRF52840 芯片,集成 Cortex-M4F 内核,主频 64 MHz,拥有 1 MB Flash 和 256 KB RAM。其最大优势是板载丰富的传感器:IMU(LSM9DS1)、麦克风(MP34DT05)、温湿度(HTS221)、气压(LPS22HH)、环境光(APDS9960),非常适合做多模态异常检测的原型验证。
ESP32 系列(如 ESP32-WROOM-32)则采用 Xtensa LX6 双核处理器,主频可达 240 MHz,拥有 4 MB Flash 和 520 KB SRAM。虽然板载传感器较少,但内置 Wi-Fi 和蓝牙,适合需要将告警信息上报到本地服务器或云端的场景。ESP32-S3 型号还增加了向量指令扩展,对神经网络推理有更好的加速效果。
| 对比维度 | Arduino Nano 33 BLE Sense | ESP32 (经典款) |
|---|---|---|
| 主控芯片 | Nordic nRF52840 (Cortex-M4F) | Espressif Xtensa LX6 双核 |
| 主频 | 64 MHz | 240 MHz |
| Flash / SRAM | 1 MB / 256 KB | 4 MB / 520 KB |
| 板载传感器 | 9 轴 IMU、麦克风、温湿度、气压、光感 | 通常无,需外接 |
| 无线连接 | BLE 5.0 | Wi-Fi + BLE 4.2 |
| 推理性能 | 中等,适合小模型(<100KB) | 较强,适合中等模型(<300KB) |
| 开发工具链 | Arduino IDE + TFLite Micro 库 | ESP-IDF + TFLite Micro / ESP-DL |
| 典型功耗 | ~5 mA(活跃),~2 µA(睡眠) | ~50 mA(活跃),~10 µA(睡眠) |
2.4 案例拆解:基于 Arduino Nano 33 BLE Sense 的电机振动异常检测
我们以一个工业电机振动监测场景为例,说明如何利用 TinyML 在 MCU 上实现异常检测闭环。该场景的约束是:电机附近无 Wi-Fi 覆盖,只能通过 BLE 将告警信息发送到 10 米内的网关;电池供电,要求至少连续工作 30 天;检测目标是识别轴承磨损初期的振动特征变化。
初始现象与目标:电机正常运行时振动频谱在 50 Hz 附近有稳定峰值,当轴承磨损时,会出现 200-300 Hz 的高频冲击成分。目标是在 MCU 上实时分析振动数据,当高频能量占比超过阈值时触发本地 LED 告警,并通过 BLE 发送一条包含时间戳和异常分数的消息。
关键参数与实现步骤:
- 数据采集:使用 IMU 的加速度计,设置采样率 1 kHz,量程 ±4g。每次采集 256 个样本(约 256 ms),窗口重叠 50%。DMA 将数据直接搬运到 RAM 缓冲区,CPU 仅在缓冲区满时被唤醒。
- 特征提取:对 256 点数据做 FFT,计算 50 Hz 附近的基频能量(40-60 Hz 频带)和 200-300 Hz 的高频能量。特征向量为 2 维:高频能量比、总能量方差。
- 模型推理:使用一个 2 层全连接神经网络(输入 2 节点,隐藏层 8 节点,输出 1 节点),模型大小约 1.2 KB。在 nRF52840 上推理时间约 3 ms,远小于采样周期。
- 本地执行:当输出概率 > 0.8 时,置位 GPIO 驱动 LED 闪烁,同时通过 BLE 发送告警数据包。为避免频繁触发,设置 10 秒的去抖窗口。
结果与复盘:实测系统在 64 MHz 主频下,CPU 负载约 12%,电池续航达到 35 天(使用 500 mAh 锂电池)。相比云端方案,本地推理避免了 2-3 秒的网络延迟,且在没有网络时仍能独立工作。但发现一个问题:当电机转速波动时,基频会偏移,导致特征提取不准确。解决方案是在 FFT 前先做一次粗略的基频估计,动态调整频带范围。
2.5 常见误区与设计原则
误区一:盲目追求模型精度。在 MCU 上,精度提升 1% 可能意味着模型体积增加 50%、推理时间翻倍。应优先保证异常检测的召回率,而非整体准确率,因为漏报的代价远高于误报。
误区二:忽略数据采集的实时性。很多开发者将精力集中在模型优化上,却忽略了传感器采样时序。如果采样抖动超过 10%,FFT 频谱会严重失真。务必使用硬件定时器触发采样,而非依赖软件延时。
误区三:将所有数据都发送到云端。这违背了 TinyML 的初衷。本地执行的价值在于:减少通信功耗、降低延迟、保护隐私。只有告警事件和摘要信息才需要上报。
设计原则总结:首先明确检测任务的实时性要求(是毫秒级还是秒级);其次评估传感器数据的最小有效维度,避免冗余特征;最后在硬件选型时,优先考虑板载传感器集成度高的平台以缩短开发周期。对于异常告警闭环,建议采用“本地检测 + 事件上报”的混合架构,既保证可靠性,又保留远程监控能力。