3. 部署正弦波预测模型
任务目标
本案例将训练好的正弦波预测模型(TensorFlow Lite Micro格式)部署到MCU上,实现基于历史输入样本的实时正弦波预测,并通过串口输出预测结果。核心目标是验证TFLite Micro推理链路在嵌入式平台上的完整可用性。
环境与依赖
- 硬件:STM32F746G-DISCO开发板(或任意Cortex-M4F以上、≥320KB RAM的MCU)
- 工具链:GNU Arm Embedded Toolchain 10.3+,CMake 3.16+
- 依赖库:TensorFlow Lite Micro(从tensorflow/tflite-micro官方仓库获取,版本≥2023.09)
- 模型文件:
sine_model.tflite(已量化,输入/输出均为float32,输入维度[1,1],输出维度[1,1])
模型与输入说明
模型实现函数近似:y = sin(x),输入为归一化到[-π, π]的相位值,输出为[-1, 1]的预测值。模型已通过TensorFlow训练并转换为TFLite格式,经xxd转换为C数组嵌入工程。
关键完整代码
// main.cc - TFLite Micro 正弦波预测部署
#include "tensorflow/lite/micro/micro_interpreter.h"
#include "tensorflow/lite/micro/micro_mutable_op_resolver.h"
#include "tensorflow/lite/micro/system_setup.h"
#include "tensorflow/lite/schema/schema_generated.h"
#include "sine_model_data.h" // 由xxd生成的模型数组
// 全局推理环境
constexpr int kTensorArenaSize = 2 * 1024; // 2KB张量内存池
uint8_t tensor_arena[kTensorArenaSize];
// 串口输出(STM32 HAL示例,其他平台替换为对应UART发送)
extern "C" void print_float(float val) {
char buf[32];
snprintf(buf, sizeof(buf), "%.4f\r\n", val);
HAL_UART_Transmit(&huart1, (uint8_t*)buf, strlen(buf), 100);
}
int main() {
tflite::InitializeTarget();
// 加载模型
const tflite::Model* model = tflite::GetModel(sine_model_data);
if (model->version() != TFLITE_SCHEMA_VERSION) return -1;
// 注册算子(仅FULLY_CONNECTED)
static tflite::MicroMutableOpResolver<1> resolver;
resolver.AddFullyConnected();
// 构建解释器
static tflite::MicroInterpreter interpreter(model, resolver, tensor_arena,
kTensorArenaSize);
if (interpreter.AllocateTensors() != kTfLiteOk) return -2;
// 获取输入/输出张量
TfLiteTensor* input = interpreter.input(0);
TfLiteTensor* output = interpreter.output(0);
// 实时预测循环:相位从0递增到2π
float phase = 0.0f;
const float step = 0.1f;
while (true) {
// 设置输入(归一化到[-π, π])
input->data.f[0] = phase - 3.14159f;
// 执行推理
if (interpreter.Invoke() != kTfLiteOk) return -3;
// 输出预测值
print_float(output->data.f[0]);
// 更新相位
phase += step;
if (phase > 6.28318f) phase = 0.0f;
// 简单延时(约100ms)
HAL_Delay(100);
}
}
构建与烧录
# 1. 获取TFLite Micro源码并添加本文件
git clone https://github.com/tensorflow/tflite-micro.git
cd tflite-micro
# 将main.cc放入tensorflow/lite/micro/examples/sine_deploy/
# 将sine_model_data.h放入同目录
# 2. 生成模型头文件(若尚未生成)
xxd -i sine_model.tflite > sine_model_data.h
# 编辑头文件,将数组名改为sine_model_data
# 3. 使用CMake交叉编译(以STM32F746G-DISCO为例)
make -f tensorflow/lite/micro/tools/make/Makefile \
TARGET=stm32f746g \
OPTIMIZED_KERNEL_DIR=cmsis_nn \
BUILD_TYPE=release \
sine_deploy
# 4. 烧录生成的bin文件到开发板
# 使用STM32CubeProgrammer或OpenOCD
验证方法与判定标准
- 串口输出检查:以115200波特率打开串口,应持续收到数值输出,格式为
xxxx(4位小数)。 - 数值正确性:采集10个连续输出值,与
sin(phase-π)的理论值对比,最大误差应<0.05(量化模型精度范围)。 - 周期性验证:输出值应呈现正弦波形周期变化,周期约为
2π/0.1×0.1s ≈ 6.28s。 - 稳定性:持续运行5分钟无死机、无输出中断。
常见问题
- 张量内存不足:若
AllocateTensors()返回错误,将kTensorArenaSize增大至4KB或8KB。 - 算子不支持:若模型含其他算子(如激活函数),需在
resolver中对应添加,例如resolver.AddRelu()。 - 输出恒为0:检查输入归一化是否正确,模型训练时的输入范围必须与部署时一致。