2. TensorFlow模型转换为ONNX基础
任务目标
本案例将完成一个TensorFlow Keras模型到ONNX格式的转换,并验证转换前后模型的推理结果一致性。你将得到一个可直接运行的完整示例,包含模型构建、格式转换、推理对比三个环节。
环境依赖
需要安装以下Python包(建议Python 3.8+):
tensorflow==2.13.0
tf2onnx==1.15.1
onnxruntime==1.16.0
numpy
完整实现代码
以下代码完成从Keras模型创建到ONNX转换及推理对比的完整流程:
import numpy as np
import tensorflow as tf
import tf2onnx
import onnxruntime as ort
# 1. 构建一个简单的Keras模型(用于演示转换流程)
model = tf.keras.Sequential([
tf.keras.layers.Dense(16, activation='relu', input_shape=(4,)),
tf.keras.layers.Dense(3, activation='softmax')
])
model.compile(optimizer='adam', loss='categorical_crossentropy')
# 2. 固定输入数据(保证可复现性)
input_data = np.array([[0.5, 1.2, -0.3, 2.1]], dtype=np.float32)
# 3. Keras模型推理(作为对比基准)
keras_output = model.predict(input_data, verbose=0)
# 4. 转换为ONNX格式
onnx_model, _ = tf2onnx.convert.from_keras(model, opset=13)
onnx_path = "keras_model.onnx"
with open(onnx_path, "wb") as f:
f.write(onnx_model.SerializeToString())
# 5. 使用ONNX Runtime加载并推理
sess = ort.InferenceSession(onnx_path)
onnx_input_name = sess.get_inputs()[0].name
onnx_output = sess.run(None, {onnx_input_name: input_data})[0]
# 6. 对比推理结果
print("Keras输出:", keras_output)
print("ONNX输出:", onnx_output)
print("最大误差:", np.max(np.abs(keras_output - onnx_output)))
运行方式
将上述代码保存为convert_keras_to_onnx.py,在安装依赖后直接执行:
python convert_keras_to_onnx.py
验证方法与通过标准
运行脚本后,观察控制台输出:
- 程序正常结束且无异常抛出;
- 当前目录下生成
keras_model.onnx文件; - Keras输出与ONNX输出的最大误差应小于1e-5(由于浮点运算差异,极小误差属正常现象)。
满足以上三点即视为转换成功且推理结果一致。
常见问题
- opset版本过低:若转换报错,尝试将
opset=13改为更高版本(如15或17)。 - 输入维度不匹配:ONNX Runtime要求输入为Numpy数组且shape需与模型定义一致,本示例中为
(1, 4)。 - 动态维度支持:本示例使用固定batch size=1。若需动态batch,需在转换时指定
inputs_as_nchw或使用tf2onnx的signaturedef参数,但本案例不涉及此场景。