必须先调用模型或显式build()再保存,否则报错;正确做法是用示例输入调用模型后save_model(),路径须为目录且推荐显式指定save_format='tf'。

直接导出即可,但必须确保模型已构建完成且权重已加载,否则会报 ValueError: Model hasn't been built yet 或保存空结构。
确认模型状态:build 和 compile 都不是必须的,但 call 必须能执行
SavedModel 保存的是可调用的计算图,核心要求是模型在保存前至少被调用过一次(触发内部层的 build),或显式调用 build()。仅 compile() 不足以生成可序列化的图。
- ✅ 正确做法:先用示例输入调用模型,如
model(tf.random.normal((1, 224, 224, 3))),再保存 - ✅ 替代做法:若已知输入形状,可显式
model.build(input_shape=(None, 224, 224, 3)) - ❌ 错误做法:定义完模型立刻
tf.keras.models.save_model(model, 'path'),此时各层kernel等变量尚未创建 - ⚠️ 注意:使用
tf.function包裹的自定义训练循环不影响保存,只要模型本身可调用即可
使用 tf.keras.models.save_model() 时路径和参数的关键细节
save_model() 是最直接的方式,但默认行为容易引发兼容性问题,尤其在跨环境部署时。
- ✅ 必须指定目录路径,不能是文件名:
tf.keras.models.save_model(model, 'my_model_dir')(末尾不加.h5或.zip) - ✅ 推荐显式指定
save_format='tf'(虽然它是默认值,但显式写出可避免未来版本变更风险) - ❌ 不要混用
include_optimizer=True:SavedModel 会保存优化器状态,但推理时完全不需要;除非你要继续训练,否则设为False - ⚠️ 若模型含自定义对象(如自定义层、损失函数),必须传入
custom_objects参数——但注意:这仅影响加载,不影响保存过程本身
验证导出是否成功:检查 SavedModel 目录结构和签名
导出后不能只看文件是否存在,要确认其符合 TensorFlow Serving / TFLite / TF.js 的预期结构。
- ✅ 进入导出目录,应看到
assets/、variables/和saved_model.pb三个核心项 - ✅ 用
saved_model_cli show --dir my_model_dir --all查看签名(signature_def),确认有serving_default且输入输出张量名、shape 正确 - ✅ 在 Python 中快速验证:用
tf.keras.models.load_model('my_model_dir')加载并跑一个 inference,检查输出 shape 是否匹配 - ⚠️ 常见坑:自定义
call()中用了未 trace 的 Python 控制流(如if isinstance(x, tf.Tensor)),会导致保存后加载时报KeyError: 'serving_default'
真正容易被忽略的是模型中隐式依赖的 Python 状态——比如在 call() 里读了全局变量、调用了未包装的 NumPy 函数,或者用了 tf.py_function。这些在保存时不会报错,但加载后在纯图模式下会直接失败。导出前务必用 tf.function 跟踪并测试完整前向流程。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











