3. 图像分类模型部署
任务目标
本案例将完成MobileNetV2图像分类模型的端侧部署闭环:将Keras预训练模型转换为TensorFlow Lite格式,并在Python环境中模拟端侧推理,对单张输入图片输出Top-1类别标签与置信度。转换后的.tflite文件可直接用于Android/iOS等端侧集成。
环境依赖
- TensorFlow ≥ 2.6(含TFLite Converter与Interpreter)
- NumPy、Pillow(图片预处理)
- ImageNet类别标签文件(
imagenet_labels.txt,1000行,每行一个类别名)
完整实现代码
import numpy as np
from PIL import Image
import tensorflow as tf
# ========== 1. 转换模型 ==========
def convert_mobilenetv2_to_tflite(save_path="mobilenet_v2.tflite"):
# 加载Keras预训练模型(含ImageNet权重)
model = tf.keras.applications.MobileNetV2(
weights="imagenet", input_shape=(224, 224, 3))
# 转换为TFLite(使用默认float32精度)
converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()
with open(save_path, "wb") as f:
f.write(tflite_model)
print(f"模型已保存: {save_path}")
return save_path
# ========== 2. 图片预处理 ==========
def preprocess_image(image_path, target_size=(224, 224)):
img = Image.open(image_path).convert("RGB")
img = img.resize(target_size)
# MobileNetV2的预处理:像素归一化到[-1, 1]
img_array = np.array(img, dtype=np.float32)
img_array = (img_array / 127.5) - 1.0
# 增加batch维度: (1, 224, 224, 3)
return np.expand_dims(img_array, axis=0)
# ========== 3. TFLite推理 ==========
def tflite_inference(tflite_path, image_path, label_path):
# 加载标签
with open(label_path, "r") as f:
labels = [line.strip() for line in f.readlines()]
# 初始化解释器
interpreter = tf.lite.Interpreter(model_path=tflite_path)
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
# 输入数据
input_data = preprocess_image(image_path)
interpreter.set_tensor(input_details[0]["index"], input_data)
interpreter.invoke()
# 输出处理
output_data = interpreter.get_tensor(output_details[0]["index"])
scores = np.squeeze(output_data) # 去掉batch维度
top_idx = np.argmax(scores)
confidence = float(scores[top_idx])
# softmax归一化到0~1(TFLite输出为logits)
exp_scores = np.exp(scores - np.max(scores))
probs = exp_scores / np.sum(exp_scores)
confidence = float(probs[top_idx])
return labels[top_idx], confidence
# ========== 4. 执行入口 ==========
if __name__ == "__main__":
# 转换模型(首次运行需下载权重,约14MB)
tflite_path = convert_mobilenetv2_to_tflite()
# 推理示例(请替换为实际图片路径)
result = tflite_inference(
tflite_path=tflite_path,
image_path="test_cat.jpg",
label_path="imagenet_labels.txt"
)
print(f"Top-1类别: {result[0]}, 置信度: {result[1]:.4f}")
运行与验证
- 准备标签文件:下载ImageNet1000类标签,保存为
imagenet_labels.txt(每行一个类别名,顺序与模型输出层对应)。 - 准备测试图片:任选一张包含明确物体的图片(如猫、狗、汽车),命名为
test_cat.jpg放入脚本同目录。 - 执行脚本:
python tflite_deploy.py。首次运行会自动下载MobileNetV2权重,转换过程约需10~30秒。 - 通过标准:控制台输出
模型已保存: mobilenet_v2.tflite,且推理结果中Top-1类别与图片内容一致、置信度大于0.5。例如输入猫图片预期输出Top-1类别: tabby cat或Egyptian cat等猫科类别。
关键说明
- 转换得到的
mobilenet_v2.tflite约14MB,可直接集成到Android(Java/Kotlin)或iOS(Swift)项目,使用TFLite Runtime API加载推理。 - 本案例使用float32精度模型,如需进一步压缩可设置
converter.optimizations = [tf.lite.Optimize.DEFAULT]启用动态范围量化,模型可缩减至约4MB,但精度略有下降。 - 端侧部署时图片预处理(缩放、归一化)需在应用层完成,与
preprocess_image()逻辑保持一致。