2. 基于TensorFlow Lite的Hello World

任务目标

本案例将训练一个基于正弦波数据的小型全连接神经网络,使其能够根据输入数值预测对应的正弦值,并将训练后的模型转换为TensorFlow Lite格式,最终部署到微控制器(MCU)上完成推理。通过本案例,你将掌握从训练到部署的完整TinyML流程。

环境与依赖

  • Python 3.8+,安装 tensorflow==2.13.*、numpy
  • TensorFlow Lite Micro(用于MCU端推理,本案例仅生成C++数组文件)
  • 硬件可选:Arduino Nano 33 BLE Sense 或 ESP32-C3(需自行安装对应板卡支持)

实现步骤

整体流程分为三步:生成训练数据并训练模型 → 转换为TFLite并生成C++头文件 → 在MCU上运行推理。核心代码集中在第一步和第二步,第三步给出最小验证逻辑。

关键完整代码

import numpy as np
import tensorflow as tf
from tensorflow.keras import layers, models

# 1. 生成正弦波训练数据
x_train = np.random.uniform(0, 2 * np.pi, 1000).astype(np.float32)
y_train = np.sin(x_train).astype(np.float32)
x_val = np.random.uniform(0, 2 * np.pi, 200).astype(np.float32)
y_val = np.sin(x_val).astype(np.float32)

# 2. 构建小型全连接模型(适合MCU)
model = models.Sequential([
    layers.Dense(16, activation='relu', input_shape=(1,)),
    layers.Dense(16, activation='relu'),
    layers.Dense(1)
])

model.compile(optimizer='adam', loss='mse', metrics=['mae'])
model.fit(x_train, y_train, epochs=50, batch_size=32,
          validation_data=(x_val, y_val), verbose=1)

# 3. 转换为TFLite格式
converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]  # 量化优化
tflite_model = converter.convert()

# 4. 生成C++头文件(供MCU端直接包含)
cpp_array = ', '.join(f'0x{b:02x}' for b in tflite_model)
with open('sine_model.h', 'w') as f:
    f.write(f'const unsigned char sine_model[] = {{{cpp_array}}};\n')
    f.write(f'const unsigned int sine_model_len = {len(tflite_model)};\n')

print("模型已保存为 sine_model.h,大小:", len(tflite_model), "字节")

运行与验证

  1. 训练与转换:直接运行上述Python脚本。训练结束后,当前目录下会生成 sine_model.h 文件,其中包含模型二进制数据和长度。
  2. 验证模型精度(PC端):在Python中加载生成的TFLite模型,输入测试值 0.5,预期输出应接近 np.sin(0.5) ≈ 0.4794。可通过以下代码验证:
import tensorflow as tf
import numpy as np

# 加载TFLite模型并推理
interpreter = tf.lite.Interpreter(model_path='sine_model.tflite')
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()

test_input = np.array([0.5], dtype=np.float32)
interpreter.set_tensor(input_details[0]['index'], test_input)
interpreter.invoke()
output = interpreter.get_tensor(output_details[0]['index'])
print("预测值:", output[0][0], "真实值:", np.sin(0.5))

若需保存 .tflite 文件,在转换代码后添加 open('sine_model.tflite','wb').write(tflite_model) 即可。

  1. MCU端部署验证:将 sine_model.h 复制到你的MCU工程中,使用TensorFlow Lite Micro库加载模型。输入 0.5f,观察串口输出是否接近 0.4794。误差在±0.1以内即视为部署成功(量化模型会有少量精度损失)。

常见问题

  • 模型无法转换:确保Keras模型输入形状为 (None, 1),且使用 tf.lite.TFLiteConverter.from_keras_model 而非旧版API。
  • MCU端输出偏差大:检查是否启用了量化(本代码已默认启用)。若偏差超过0.2,可尝试去掉 converter.optimizations 行重新转换,但模型体积会增大。
  • 头文件过大:本模型约1-2KB,适合大多数MCU。若使用更大模型,需确认板载Flash容量。