TinyML 实战:在 MCU 上跑 AI 模型
TinyML(Tiny Machine Learning)让 AI 推理可以在微控制器上运行,无需云端连接。本文介绍如何用 AI 工具辅助,在 STM32 上部署一个手势识别模型。
一、什么是 TinyML?
TinyML 是将机器学习模型部署到低功耗微控制器上的技术。典型特征:
- 极低功耗:运行功耗 < 1mW,电池可用数年
- 超小体积:模型大小 < 100KB
- 实时推理:推理延迟 < 10ms
- 本地处理:数据不需要上传云端,保护隐私
二、开发流程
1. 数据采集
// 在 STM32 上用加速度传感器采集手势数据
// 使用 Arduino + LSM6DS3 加速度计
#define SAMPLE_RATE 119 // 119Hz 采样率
#define BUFFER_SIZE 119 // 1 秒数据
float accel_buffer[BUFFER_SIZE * 3]; // x, y, z 三轴
void collect_gesture_data(Gesture label) {
for (int i = 0; i < BUFFER_SIZE; i++) {
accel_buffer[i * 3 + 0] = accel.getX();
accel_buffer[i * 3 + 1] = accel.getY();
accel_buffer[i * 3 + 2] = accel.getZ();
delay(1000 / SAMPLE_RATE);
}
// 保存数据到 SD 卡或通过串口发送到 PC
save_to_file(label, accel_buffer, sizeof(accel_buffer));
}
2. 模型训练(在 PC 上完成)
使用 Python + TensorFlow 训练模型,然后转换为 TFLite 格式:
import tensorflow as tf
import numpy as np
# 加载采集的手势数据
X_train, y_train = load_gesture_data("train/")
X_test, y_test = load_gesture_data("test/")
# 构建简单的 CNN 模型
model = tf.keras.Sequential([
tf.keras.layers.Conv1D(8, 3, activation='relu',
input_shape=(119, 3)),
tf.keras.layers.MaxPooling1D(2),
tf.keras.layers.Conv1D(16, 3, activation='relu'),
tf.keras.layers.GlobalAveragePooling1D(),
tf.keras.layers.Dense(4, activation='softmax') # 4 种手势
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(X_train, y_train, epochs=50, validation_split=0.2)
# 转换为 TFLite(量化为 INT8)
converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_types = [tf.int8]
tflite_model = converter.convert()
with open("gesture_model.tflite", "wb") as f:
f.write(tflite_model)
print(f"Model size: {len(tflite_model)} bytes")
3. AI 辅助移植到 STM32
让 AI 帮你生成 TFLite Micro 的 C 推理代码:
// 提示词:
// "帮我写一个 STM32F4 上运行 TFLite Micro 的完整工程,
// 使用 CMSIS-NN 加速,输入是 119 个时间步的加速度数据(x,y,z),
// 输出是 4 种手势的分类结果"
// AI 可以生成:
// - TFLite Micro 初始化代码
// - 模型加载和内存分配
// - 推理调用封装
// - CMSIS-NN 算子优化
4. 部署到 MCU
// 最终推理代码
#include "tensorflow/lite/micro/micro_interpreter.h"
#include "gesture_model_data.h"
// 内存分配(根据模型需求调整)
constexpr int kTensorArenaSize = 8 * 1024;
uint8_t tensor_arena[kTensorArenaSize];
tflite::MicroInterpreter interpreter(
tflite::GetModel(gesture_model_data),
resolver, tensor_arena, kTensorArenaSize);
// 运行推理
void run_inference(float* accel_data) {
TfLiteTensor* input = interpreter.input(0);
// 将加速度数据复制到输入张量
for (int i = 0; i < 119 * 3; i++) {
input->data.int8[i] = quantize(accel_data[i]);
}
// 执行推理
interpreter.Invoke();
// 获取结果
TfLiteTensor* output = interpreter.output(0);
int predicted_class = argmax(output->data.int8, 4);
printf("Predicted gesture: %s\n",
gesture_names[predicted_class]);
}
三、性能优化技巧
内存优化
- 模型量化:FP32 → INT8,模型大小缩小 4 倍
- 层剪枝:移除不重要的神经元,减少计算量
- 知识蒸馏:用大模型训练小模型,保持精度
速度优化
- CMSIS-NN:ARM 官方的神经网络加速库
- ESP-DSP:Espressif 的 DSP 加速库
- DMA 传输:传感器数据通过 DMA 传输,CPU 不阻塞
四、AI 辅助开发的实用提示词
// 1. 模型优化
// "这个 TFLite 模型在 STM32F4 上推理需要 50ms,太慢了。
// 帮我分析瓶颈并优化,目标是 <10ms"
// 2. 内存分析
// "当前模型需要 12KB tensor arena,STM32F407 只有 192KB RAM。
// 帮我分析内存使用,给出优化建议"
// 3. 精度调试
// "模型在 PC 上准确率 95%,部署到 MCU 后降到 80%。
// 可能是什么原因?如何排查?"
// 4. 低功耗设计
// "如何让手势识别模块在待机时功耗低于 10uW?
// 需要支持唤醒后立即推理"
五、应用场景
- 智能家居:手势控制灯光、窗帘、空调
- 可穿戴设备:运动识别、跌倒检测、睡眠监测
- 工业检测:振动分析、设备预测性维护
- 医疗健康:心率异常检测、呼吸监测
- 农业:作物病害识别、土壤分析
TinyML 让 AI 走出云端,真正进入万物互联的边缘世界。
六、学习资源
- TensorFlow Lite for Microcontrollers
- STM32Cube.AI:ST 官方的 AI 部署工具
- TensorFlow Lite Arduino Library
- Edge Impulse:在线 TinyML 开发平台
TinyML 的门槛正在被 AI 工具大幅降低。以前需要深厚的 ML 功底才能完成的模型优化和部署,现在可以通过 AI 辅助快速完成。但理解底层原理仍然重要——它能帮你做出更好的架构决策,也能在 AI 给出错误建议时及时纠正。
推荐产品
TinyML 开发所需硬件,点击链接查看详情(Amazon 联盟链接):
- 🔌 ST-Link V2 调试器 - 烧录和调试 STM32
- 📊 USB 逻辑分析仪 - 调试 I2C/SPI 通信
- 🔧 Arduino 传感器套件 - 包含加速度计等传感器
- 📚 STM32F407 Discovery - 官方开发板