1. 基于TFLite Micro的端到端推理流程搭建

任务目标

在MCU(以STM32F407为例)上部署一个TFLite Micro模型,完成从模型转换到推理输出的完整流程。本案例使用一个预先训练好的正弦波拟合模型(sine_model.tflite),演示如何将其转换为C数组、集成到嵌入式工程中,并执行一次前向推理得到预测值。

环境与依赖

  • 硬件:STM32F407 Discovery开发板(或任意Cortex-M4/M7 MCU,需≥16KB RAM)
  • 软件:STM32CubeIDE(或任意支持ARM GCC的IDE)、TFLite Micro库(v2.14+)
  • 模型来源:使用TensorFlow训练的正弦波拟合模型,输入为1个float(弧度值),输出为1个float(正弦预测值)

模型转换与C数组生成

在PC端使用Python将TensorFlow模型转换为TFLite格式,再生成C头文件。转换命令如下:

# 转换命令(PC端执行)
import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model("sine_model")
converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_model = converter.convert()
with open("sine_model.tflite", "wb") as f:
    f.write(tflite_model)

# 生成C数组(使用xxd工具)
xxd -i sine_model.tflite > sine_model_data.h

生成的sine_model_data.h包含unsigned char sine_model_tflite[]数组及其长度变量,直接复制到嵌入式工程中。

关键完整代码

以下代码实现完整的推理流程:加载模型、设置输入张量、执行推理、读取输出。使用TFLite Micro的C++ API。

#include "tensorflow/lite/micro/micro_interpreter.h"
#include "tensorflow/lite/micro/micro_mutable_op_resolver.h"
#include "tensorflow/lite/schema/schema_generated.h"
#include "sine_model_data.h"

// 定义arena大小(根据模型需求调整)
constexpr int kTensorArenaSize = 2 * 1024;
uint8_t tensor_arena[kTensorArenaSize];

// 模型推理函数:输入弧度值,返回正弦预测
float run_inference(float input_value) {
    // 1. 加载模型
    const tflite::Model* model = tflite::GetModel(sine_model_tflite);
    if (model->version() != TFLITE_SCHEMA_VERSION) {
        return -1.0f;  // 版本不匹配
    }

    // 2. 注册算子(仅需FULLY_CONNECTED,因为正弦模型是简单全连接网络)
    static tflite::MicroMutableOpResolver<10> resolver;
    resolver.AddFullyConnected();
    resolver.AddSoftmax();  // 若模型包含softmax则保留

    // 3. 构建解释器
    static tflite::MicroInterpreter interpreter(model, resolver, tensor_arena, kTensorArenaSize);
    
    // 4. 分配张量内存
    if (interpreter.AllocateTensors() != kTfLiteOk) {
        return -1.0f;
    }

    // 5. 获取输入/输出张量
    TfLiteTensor* input = interpreter.input(0);
    TfLiteTensor* output = interpreter.output(0);

    // 6. 设置输入值
    input->data.f[0] = input_value;

    // 7. 执行推理
    if (interpreter.Invoke() != kTfLiteOk) {
        return -1.0f;
    }

    // 8. 读取输出
    return output->data.f[0];
}

// 主函数(测试入口)
int main() {
    // 测试:预测 sin(0.5) ≈ 0.4794
    float result = run_inference(0.5f);
    
    // 通过调试串口或断点观察result值
    // 预期输出:0.4794(与代码逻辑严格一致)
    while(1) {}
}

工程集成要点

  1. 将sine_model_data.h和上述代码放入工程,添加TFLite Micro源码路径(tensorflow/lite/micro目录)
  2. 链接时需要包含CMSIS-NN优化库(可选,但推荐用于Cortex-M4)
  3. 在IDE中设置C++标准为C++11或以上,并启用-fno-rtti和-fno-exceptions以减小代码体积

验证方法与判定标准

  • 编译验证:工程编译无错误,固件烧录后程序不进入HardFault
  • 功能验证:在main()中设置断点或通过串口输出result值,观察是否接近0.4794(理论值sin(0.5))
  • 通过条件:输出值与理论值误差小于0.01,且连续运行10次结果稳定

常见问题

  • 内存不足:增大kTensorArenaSize,或使用MicroMutableOpResolver时只注册实际用到的算子
  • 算子不支持:若模型包含未注册算子,在resolver中调用对应的AddXXX()方法
  • 模型版本不匹配:确保TFLite Micro版本与转换模型的TensorFlow版本兼容(推荐TF 2.14+)