第一讲:课程导学与环境搭建
各位同学好,欢迎来到《微控制器上的TensorFlow部署实战》。我是你们的讲师,一个在嵌入式AI领域摸爬滚打多年的工程师。
这一讲,咱们先不急着写代码。先把路铺好,把工具备齐。说白了,就是搞清楚三件事:TensorFlow Lite Micro是什么、它能跑在哪些板子上、怎么把开发环境搭起来。最后,我们会跑通一个Hello World示例,让你亲眼看到模型在单片机上亮灯或打印数据。
1.1 TensorFlow Lite Micro 到底是什么?
TensorFlow Lite Micro,简称TFLM。它是TensorFlow Lite的一个子集,专门为微控制器设计的推理引擎。
你想想看,普通的TensorFlow模型动辄几十MB,而STM32的Flash可能只有512KB。怎么塞得进去?TFLM就是来解决这个矛盾的。它把模型解释器精简到极致,核心代码只有几千行,占用RAM通常不到几十KB。
它的核心特点:
- 极小的内存占用:我见过最精简的TFLM实例,RAM只用了不到16KB。
- 无操作系统依赖:裸机也能跑,当然RTOS也支持。
- 纯C++实现:没有动态内存分配,没有标准库依赖。
- 支持量化模型:int8量化是主流,速度比浮点快3-5倍。
重要概念区分:
TensorFlow Lite(手机端) vs TensorFlow Lite Micro(MCU端)
前者支持GPU加速、NNAPI,后者只支持CPU逐层推理。但TFLM的代码量只有前者的十分之一左右。
1.2 硬件选型:STM32 / ESP32 / Cortex-M
我个人习惯把硬件分成三类:入门级、进阶级、专业级。咱们课程主要覆盖前两类。
| 芯片系列 | 典型型号 | Flash | RAM | 适合场景 |
|---|---|---|---|---|
| STM32F4系列 | STM32F407 | 1MB | 192KB | 入门学习、传感器分类 |
| STM32H7系列 | STM32H743 | 2MB | 1MB | 中等复杂度模型、音频处理 |
| ESP32系列 | ESP32-S3 | 8MB | 512KB | 带WiFi/蓝牙、需要OTA更新 |
| Cortex-M4/M7 | 通用内核 | 视厂商而定 | 视厂商而定 | 工业级产品、低功耗场景 |
这里有个避坑指南:我曾经在STM32F103上尝试跑一个稍微大点的模型,结果Flash不够,折腾了两天才发现是芯片选型的问题。所以,如果你刚开始学,建议直接用STM32F407或ESP32-S3,别在资源太紧的芯片上折磨自己。
1.3 开发环境搭建:PlatformIO vs CMake
搭建环境往往是新手最头疼的一步。我见过太多同学卡在这里。咱们分两条路走:
方案一:PlatformIO(推荐新手)
PlatformIO是VS Code的一个插件。它帮你管理编译器、库依赖、烧录工具。说白了,你装好它,点一下按钮,代码就编译烧录了。
安装步骤:
- 安装VS Code
- 在扩展中搜索PlatformIO IDE并安装
- 重启VS Code,等待PlatformIO初始化完成
- 新建项目,选择你的开发板型号
我的小技巧:PlatformIO的库管理器非常好用。你只需要在platformio.ini里写上依赖库的名字,它会自动下载。比如要使用TFLM,写上:
lib_deps =
tensorflow/tensorflow-lite-micro @ ^2.12.0
方案二:CMake + ARM GCC(推荐进阶用户)
如果你习惯命令行,或者需要集成到CI/CD流程中,CMake是更好的选择。
基本流程:
- 安装ARM GCC工具链(gcc-arm-none-eabi)
- 安装CMake(3.16以上版本)
- 下载TFLM源码:
git clone https://github.com/tensorflow/tflite-micro.git - 创建build目录,运行cmake配置
mkdir build && cd build
cmake .. -DTARGET=STM32F407
make -j4
注意:CMake方式需要你自己配置链接脚本和启动文件。如果你对MCU底层不熟,建议先用PlatformIO。我刚开始用CMake时,光链接脚本就折腾了一下午。
1.4 Hello World 示例:编译与烧录
好了,环境搭好了,咱们来跑第一个例子。这个例子的功能很简单:输入一个正弦波的角度,模型输出对应的正弦值。说白了,就是让MCU学会计算sin函数。
代码结构:
hello_world/
├── main.cpp # 主程序
├── model.h # 量化后的模型数据(二进制数组)
├── model.cpp # 模型加载代码
├── constants.h # 常量定义
└── platformio.ini # 项目配置文件
核心代码片段(main.cpp):
#include "tensorflow/lite/micro/all_ops_resolver.h"
#include "tensorflow/lite/micro/micro_interpreter.h"
#include "model.h"
// 分配内存池
constexpr int kTensorArenaSize = 2 * 1024;
uint8_t tensor_arena[kTensorArenaSize];
void setup() {
// 加载模型
const tflite::Model* model = tflite::GetModel(g_model);
// 创建解释器
static tflite::MicroMutableOpResolver<10> resolver;
static tflite::MicroInterpreter interpreter(model, resolver,
tensor_arena, kTensorArenaSize);
// 分配张量
interpreter.AllocateTensors();
// 获取输入输出
float* input = interpreter.input(0)->data.f;
float* output = interpreter.output(0)->data.f;
// 推理
*input = 1.57f; // 90度
interpreter.Invoke();
// 输出结果
printf("sin(90°) = %f\n", *output);
}
编译烧录步骤(PlatformIO):
- 在VS Code中打开项目文件夹
- 点击底部状态栏的「→」箭头(Build)
- 等待编译完成(第一次会下载依赖,稍慢)
- 连接开发板,点击「→」旁边的「→·」按钮(Upload)
预期结果:
串口输出:sin(90°) = 0.998765(接近1.0,因为模型是量化的,有微小误差)
如果板子上有LED,可以观察到LED按正弦波规律呼吸闪烁。
1.5 常见问题与排错
嗯,这里我总结几个我经常被问到的问题:
- 编译报错:找不到头文件 → 检查platformio.ini中的lib_deps是否写对了版本号
- 烧录后没反应 → 检查串口波特率是否匹配(通常115200)
- 模型推理结果全为0 → 检查输入数据是否在量化范围内(int8模型输入需归一化到[-128, 127])
我曾经遇到一个特别坑的问题:模型在PC上推理完全正确,烧到MCU上结果全错。查了两天,最后发现是字节序问题——MCU是小端模式,而模型文件是大端存储。所以,记得在模型转换时指定--byte_order=little。
1.6 本章小结
这一讲,咱们把地基打好了。你知道了TFLM是什么,选什么硬件合适,怎么搭环境,还跑通了第一个Hello World。说实话,能走到这一步,你已经超过了80%的初学者。
下一讲,我们会深入模型转换的细节。你会学到如何把Keras模型转换成.tflite文件,再转换成C数组,最后烧到MCU上。到时候,你就可以跑自己的模型了。
记住:嵌入式AI的核心不是算法多牛,而是在资源受限的环境下把算法跑起来。这条路没有捷径,但每一步都算数。
咱们下节课见。