3、TinyML基础:TinyML定义、边缘设备约束、典型工作流程(数据→模型→部署)
在工业振动检测场景中,传统做法是将传感器数据通过网关上传至云端或本地服务器,由GPU集群完成推理。但这一路径在产线实时性、数据隐私和网络稳定性方面存在天然瓶颈。TinyML(Tiny Machine Learning)正是在这一矛盾中诞生的工程范式——它并非简单地将模型“压缩”后塞进单片机,而是围绕内存以KB计、算力以MHz计、功耗以mW计的极端约束,重新设计从数据采集到推理部署的完整技术链路。本章将厘清TinyML的定义边界,剖析边缘设备的硬性约束,并拆解“数据→模型→部署”的标准工作流,为后续振动检测模型的延迟优化与推理加速奠定方法论基础。
3.1 TinyML定义:并非“小模型”那么简单
TinyML是机器学习与嵌入式物联网的交叉学科,其官方定义由TinyML基金会提出:在功耗受限、资源受限的终端设备上,使能机器学习推理的技术与工程实践。这里的“Tiny”不仅指模型参数量小,更强调端侧闭环——数据在本地完成采集、预处理、推理和决策,仅在必要时上传结果或异常片段。
与云端AI相比,TinyML有三个本质区别:
- 推理位置:云端AI在数据中心完成推理,TinyML在传感器节点或MCU上完成,数据不出设备。
- 资源预算:云端以GPU/TPU为算力基础,TinyML以Cortex-M系列MCU为典型载体,RAM预算通常小于1MB。
- 优化目标:云端追求吞吐量和精度,TinyML优先考虑延迟确定性、峰值内存和功耗,精度是约束条件下的次优解。
在振动检测场景中,TinyML的典型任务包括:轴承故障分类(正常/内圈/外圈/滚动体)、不平衡检测、转速异常预警等。这些任务通常采用1D-CNN或轻量级LSTM,参数量控制在10万以内,推理延迟要求低于50ms。
3.2 边缘设备约束:振动检测的“镣铐”清单
振动检测设备通常部署在电机轴承座、泵体或齿轮箱附近,环境温度高、振动大、布线困难,因此对硬件有严苛要求。下表总结了典型边缘设备的约束参数及对模型设计的影响:
| 资源维度 | 典型范围 | 对模型设计的约束 | 振动检测场景示例 |
|---|---|---|---|
| RAM | 64KB ~ 1MB | 激活值内存必须小于RAM的60%,否则导致堆栈溢出 | STM32F4系列(192KB RAM)需控制特征图尺寸 |
| Flash | 256KB ~ 4MB | 模型权重+代码+运行时库的总和需小于Flash的80% | ESP32-S3(8MB Flash)可容纳INT8量化后的1D-CNN |
| 算力 | 50MHz ~ 400MHz | 乘加运算次数(MACs)需控制在10M以内,保证实时性 | Cortex-M7 @400MHz 可运行5万参数模型 |
| 功耗 | 1mW ~ 100mW | 推理功耗+传感器采样功耗需低于电池容量/预期寿命 | CR2032电池(220mAh)需将单次推理功耗控制在0.5mJ |
| 外设接口 | I2C/SPI/UART | 传感器数据需通过DMA搬运,避免CPU干预 | ADXL345加速度计通过SPI以3200Hz采样 |
除了硬件参数,还有两个常被忽视的约束:
- 数值精度:多数MCU不支持FP32加速,需使用INT8或FP16。振动信号动态范围大(振幅可达±16g),量化时需做自适应缩放,否则小故障特征会被量化噪声淹没。
- 实时性:振动检测要求“采样-推理-决策”在一个采样周期内完成。例如采样率3200Hz时,周期为312.5μs,但通常允许缓冲多个周期(如256点)后批量推理,此时推理延迟需小于80ms。
3.3 典型工作流:数据→模型→部署的工程闭环
TinyML项目并非线性流程,而是迭代优化的闭环。以下为振动检测场景的标准工作流拆解:
阶段一:数据采集与预处理
振动数据采集需关注三个关键参数:采样率(至少为最高分析频率的2.56倍)、采样时长(至少包含10个旋转周期)、通道数(单轴/三轴)。原始数据需经过以下预处理:
- 去直流分量:消除加速度计零偏,避免直流分量占据INT8量化范围。
- 带通滤波:保留1kHz~5kHz频段(轴承故障特征频率通常在此范围),滤除低频摆动和高频噪声。
- 归一化:将数据缩放到[-1,1]区间,便于量化。
- 滑窗分割:每256点为一个样本,重叠率50%,以增强数据多样性。
// 伪代码示例:振动数据预处理
#define SAMPLE_RATE 3200
#define WINDOW_SIZE 256
#define STRIDE 128
float raw_buffer[WINDOW_SIZE];
float processed_buffer[WINDOW_SIZE];
// 1. 去直流
float mean = 0;
for (int i = 0; i < WINDOW_SIZE; i++) mean += raw_buffer[i];
mean /= WINDOW_SIZE;
// 2. 带通滤波(二阶IIR,系数预计算)
for (int i = 0; i < WINDOW_SIZE; i++) {
processed_buffer[i] = b0 * (raw_buffer[i] - mean) + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2;
x2 = x1; x1 = raw_buffer[i] - mean;
y2 = y1; y1 = processed_buffer[i];
}
// 3. 归一化到[-1,1]
float max_val = 0;
for (int i = 0; i < WINDOW_SIZE; i++) {
if (fabs(processed_buffer[i]) > max_val) max_val = fabs(processed_buffer[i]);
}
for (int i = 0; i < WINDOW_SIZE; i++) processed_buffer[i] /= max_val;
阶段二:模型训练与轻量化
振动检测模型首选1D-CNN,因其对时序特征提取高效且参数量少。训练流程如下:
- 在PC端使用TensorFlow/Keras训练FP32模型,输入形状为(256, 1)或(256, 3)(三轴)。
- 使用剪枝移除权重绝对值小于阈值的连接,通常可减少30%~50%参数。
- 使用量化感知训练模拟INT8推理误差,微调权重。
- 导出为TensorFlow Lite格式,再转换为C数组(.cc文件)供MCU编译。
一个典型的振动故障分类模型结构如下:
| 层类型 | 输出尺寸 | 参数量 | MACs |
|---|---|---|---|
| Conv1D (16, 3) | (256, 16) | 64 | 16,384 |
| MaxPool (2) | (128, 16) | 0 | 0 |
| Conv1D (32, 3) | (128, 32) | 1,568 | 200,704 |
| MaxPool (2) | (64, 32) | 0 | 0 |
| Flatten | 2048 | 0 | 0 |
| Dense (16) | 16 | 32,784 | 32,768 |
| Dense (4) | 4 | 68 | 64 |
| 合计 | - | 34,484 | ~250K |
该模型在Cortex-M4 @168MHz上,INT8推理延迟约15ms,RAM占用约45KB,满足实时性要求。
阶段三:部署与推理优化
部署环节的核心是将TFLite模型转换为MCU可执行的C++代码。常用工具链包括:
- TensorFlow Lite for Microcontrollers (TFLM):官方支持,但需手动管理arena内存。
- STM32Cube.AI:针对STM32优化,自动生成C代码,支持硬件加速。
- Edge Impulse:端到端平台,适合快速原型验证。
部署时的关键优化点:
- 内存复用:使用“算子融合”减少中间张量,例如将Conv+ReLU+MaxPool融合为单个算子。
- 查表替代激活函数:ReLU无需查表,但sigmoid/tanh需用256点查表替代。
- DMA传输:ADC采样数据通过DMA直接写入RAM,避免CPU中断开销。
tflite::MicroInterpreter的arena_size接口估算内存需求。若超出RAM,优先减少第一层卷积核数量(对内存影响最大),而非减少深度。
3.4 案例拆解:电机轴承故障诊断的TinyML落地
背景与约束:某化工厂的循环水泵电机(转速2980rpm)频繁出现轴承过热停机。原方案采用有线振动传感器连接PLC,但布线成本高且无法覆盖所有关键点位。现要求设计无线节点:采用nRF52840(Cortex-M4F,256KB RAM,1MB Flash),电池供电(2节AA,容量2000mAh),目标工作寿命≥6个月。
初始现象与目标:电机轴承外圈故障特征频率BPFO≈89Hz(根据轴承型号计算)。需在故障早期(故障特征频率幅值超过正常值3倍)时报警。采样率设为2560Hz,每次采集256点(0.1s),每10s采集一次。
关键输入数据与参数:
- 加速度计:ADXL345,±16g,SPI接口,采样率2560Hz。
- 模型输入:256点单轴振动波形。
- 分类目标:正常/外圈故障/内圈故障/滚动体故障(4类)。
- 功耗预算:采样+推理+无线传输总功耗≤0.5mW(平均)。
分析判断过程:
- 在PC端采集正常和故障数据各2000组,按7:3划分训练/验证集。
- 训练1D-CNN模型(结构如上表),FP32精度97.2%。
- 进行INT8量化感知训练,精度降至95.8%,仍在可接受范围。
- 使用STM32Cube.AI生成C代码,实测推理延迟18ms,RAM占用52KB。
- 功耗实测:采样(DMA模式)功耗12mA×0.1s=1.2mAs;推理功耗8mA×18ms=0.144mAs;无线发送(BLE)功耗15mA×5ms=0.075mAs。单次循环总功耗约1.42mAs,每10s一次,平均电流0.142mA。电池容量2000mAh,理论寿命约1.6年,满足6个月要求。
实际操作步骤:
# 1. 数据采集脚本(Python,通过串口接收)
import serial, numpy as np
ser = serial.Serial('COM3', 115200)
samples = []
for _ in range(256):
samples.append(int(ser.readline()))
np.save('vibration_sample.npy', np.array(samples))
# 2. 训练脚本(TensorFlow)
model = tf.keras.Sequential([
tf.keras.layers.Conv1D(16, 3, activation='relu', input_shape=(256,1)),
tf.keras.layers.MaxPool1D(2),
tf.keras.layers.Conv1D(32, 3, activation='relu'),
tf.keras.layers.MaxPool1D(2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(16, activation='relu'),
tf.keras.layers.Dense(4, activation='softmax')
])
# 量化感知训练
import tensorflow_model_optimization as tfmot
quantize_model = tfmot.quantization.keras.quantize_model
q_model = quantize_model(model)
q_model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
q_model.fit(x_train, y_train, epochs=20, validation_data=(x_val, y_val))
结果对比与复盘:
| 指标 | FP32模型 | INT8量化模型 | 优化幅度 |
|---|---|---|---|
| 模型大小 | 138KB | 35KB | -74.6% |
| 推理延迟 | 62ms | 18ms | -71.0% |
| RAM占用 | 128KB | 52KB | -59.4% |
| 精度 | 97.2% | 95.8% | -1.4% |
风险与代价:量化后模型对早期微弱故障(幅值仅超阈值1.5倍)的检测灵敏度下降,需将报警阈值从3倍调整为2.5倍。此外,电池在低温环境下容量衰减约20%,需在固件中加入电压监测,低于2.4V时提高采样间隔至30s。
复盘经验:
- 振动检测的TinyML项目,数据预处理(尤其是滤波和归一化)对量化精度的提升远大于模型结构调整。
- 使用STM32Cube.AI比TFLM在Cortex-M4上快约15%,因其利用了硬件FPU和SIMD指令。
- 务必在部署前用
random_test数据验证量化模型的鲁棒性,避免在真实振动环境中出现“量化死区”。
3.5 常见误区与总结复盘
在TinyML振动检测项目实践中,以下误区最为常见:
总结复盘:TinyML在振动检测中的成功落地,取决于三个核心能力:对设备约束的精确预算(内存、Flash、功耗)、对数据特征的深刻理解(采样率、滤波、归一化)、对部署工具链的熟练运用(量化、算子融合、DMA)。本章建立的“约束-工作流-优化”框架,将贯穿后续所有章节——延迟优化不是孤立的模型压缩,而是从数据采集那一刻就开始的全局设计。