2. TensorFlow模型训练基础:Python环境配置、Keras构建简单全连接网络、模型训练与保存、模型量化原理(FP32转INT8)
好,咱们正式开始动手了。
上一章我们聊了TFLite Micro的整体架构,你可能觉得有点虚。这一章,咱们来点实在的——把模型跑起来。不过别急,在微控制器上跑模型之前,得先在电脑上把模型训练好。这就像盖房子,你得先有设计图,才能施工。
2.1 Python环境配置:别让环境卡住你
我个人习惯用Anaconda来管理Python环境。为什么?因为项目多了,依赖冲突真的让人头大。我曾经在一个项目里,因为TensorFlow和OpenCV的版本不兼容,折腾了整整一个下午。从那以后,我就老老实实用虚拟环境了。
配置步骤其实很简单,你跟着我来:
- 安装Anaconda(或者Miniconda,更轻量)
- 创建虚拟环境:
conda create -n tflite_micro python=3.9 - 激活环境:
conda activate tflite_micro - 安装TensorFlow:
pip install tensorflow==2.13.0
装完之后,验证一下:
import tensorflow as tf
print(tf.__version__) # 应该输出 2.13.0
看到版本号,环境就搞定了。是不是很简单?
2.2 Keras构建简单全连接网络:从零开始搭积木
Keras是TensorFlow的高级API。说白了,就是帮你把神经网络搭积木一样拼起来。你想想看,如果让你手写反向传播和梯度下降,那得多痛苦?Keras把这些都封装好了。
咱们要构建一个全连接网络(Fully Connected Network),也叫多层感知机(MLP)。它是最基础的神经网络结构,也是TFLite Micro上最常用的结构之一。
看代码:
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten
model = Sequential([
Flatten(input_shape=(28, 28)), # 输入层:将28x28的图像展平
Dense(128, activation='relu'), # 隐藏层:128个神经元,ReLU激活
Dense(64, activation='relu'), # 隐藏层:64个神经元
Dense(10, activation='softmax') # 输出层:10个类别,Softmax归一化
])
这里我解释一下:
- Flatten:把二维图像变成一维向量。比如28x28的图片,展平后就是784个像素点。
- Dense:全连接层。每个神经元都和上一层的所有神经元相连。
- ReLU:激活函数,说白了就是让网络有非线性能力。没有它,网络再深也只是线性变换。
- Softmax:输出层专用,把输出变成概率分布,所有类别的概率加起来等于1。
2.3 模型训练与保存:让模型学会“思考”
网络搭好了,接下来就是训练。训练的过程,说白了就是让模型不断调整内部的权重,使得预测结果越来越准。
先准备数据。我们用MNIST手写数字数据集,这是深度学习的“Hello World”:
from tensorflow.keras.datasets import mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0 # 归一化到0~1
为什么要归一化?因为像素值范围是0~255,直接输入会让梯度爆炸。我刚开始学的时候没注意这个,训练出来的模型准确率只有10%,跟瞎猜一样。嗯,这个坑我踩过。
然后编译模型:
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
- optimizer:优化器,Adam是默认首选,自适应学习率,省心。
- loss:损失函数,分类问题用交叉熵。
- metrics:评估指标,我们关注准确率。
开始训练:
history = model.fit(x_train, y_train, epochs=5, validation_data=(x_test, y_test))
训练完成后,保存模型:
model.save('mnist_model.h5') # 保存为HDF5格式
2.4 模型量化原理:FP32转INT8,瘦身不减智
好,模型训练好了,准确率也还行。但问题来了——微控制器的RAM和Flash都很小,动不动就几十KB到几百KB。一个FP32的模型,参数都是32位浮点数,占空间大,计算也慢。
怎么办?量化。
量化的核心思想很简单:用更少的比特数来表示权重和激活值。最常见的是从FP32(32位浮点数)转到INT8(8位整数)。
你想想看,32位变成8位,模型大小直接缩小到原来的1/4。而且整数运算比浮点运算快得多,在MCU上简直是天壤之别。
量化原理可以用一个公式概括:
q = round(r / scale) + zero_point
- r:原始浮点值
- q:量化后的整数值
- scale:缩放因子,决定每个量化步长代表多少浮点数
- zero_point:零点偏移,让浮点0对应一个整数
举个例子:假设浮点范围是[-1.0, 1.0],要量化到INT8(范围-128~127)。那么scale = (1.0 - (-1.0)) / (127 - (-128)) ≈ 0.0078。浮点0.5量化后就是 round(0.5 / 0.0078) + 0 ≈ 64。
量化有两种方式:
| 量化类型 | 说明 | 适用场景 |
|---|---|---|
| 训练后量化(Post-training Quantization) | 模型训练完后,直接转换权重 | 快速部署,精度损失小 |
| 量化感知训练(Quantization-aware Training) | 训练过程中模拟量化效果 | 精度要求高,模型较大 |
在TensorFlow中做量化很简单,几行代码搞定:
import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_types = [tf.float16] # 或者用默认的INT8
tflite_model = converter.convert()
with open('model_quantized.tflite', 'wb') as f:
f.write(tflite_model)
好了,这一章的内容就到这里。你学会了Python环境配置、用Keras搭了一个全连接网络、训练并保存了模型,还理解了量化的基本原理。下一章,我们会把模型转换成TFLite格式,然后部署到微控制器上。到时候,模型就能在真正的硬件上跑起来了。
有什么问题,欢迎随时交流。