tf.saved_model.save要求路径为干净目录而非文件,如"./my_saved_model";模型需为tf.keras.Model或可追踪对象;加载时需区分tf.keras.models.load_model(支持.predict())与tf.saved_model.load(需signature调用)。

tf.saved_model.save 保存模型时路径必须是目录,不能是文件名
直接用 tf.saved_model.save(model, "model.h5") 会报错,因为 tf.saved_model.save 要求第二个参数是**空目录路径**,不是文件。TensorFlow 会自己在该路径下创建 assets/、variables/ 和 saved_model.pb 等结构。
常见错误现象:NotImplementedError: Saving custom objects not supported 或 TypeError: expected str, bytes or os.PathLike, not NoneType,往往是因为路径不存在或传入了带后缀的文件名。
- 正确做法:确保路径是干净目录,例如
tf.saved_model.save(model, "./my_saved_model") - 如果目录已存在,TensorFlow 默认会覆盖(不报错),但建议先清理:
import shutil; shutil.rmtree("./my_saved_model", ignore_errors=True) - 模型必须是
tf.keras.Model实例或带__call__的自定义对象,且所有计算逻辑需可追踪(即不能含纯 Python 控制流,如if x > 0:,应改用tf.cond)
加载 tf.saved_model 需用 tf.keras.models.load_model 或 tf.saved_model.load
两种加载方式用途不同,选错会导致后续调用失败:
-
tf.keras.models.load_model("./my_saved_model"):返回标准tf.keras.Model对象,支持.predict()、.fit()(如果保存时含 optimizer)、.summary()等;适合继续训练或推理 -
tf.saved_model.load("./my_saved_model"):返回一个ConcreteFunction可调用对象(或带签名的MetaGraph),更底层,适合部署场景(如 TensorFlow Serving);它不保证有.predict方法,需通过inference = loaded.signatures["serving_default"]显式调用 - 若保存时用了
signatures=...参数,加载后必须按对应 signature 名调用,否则报KeyError: 'serving_default'
保存带自定义层或损失函数的模型要显式传参
如果模型用了自定义 tf.keras.layers.Layer 或自定义 loss,tf.saved_model.save 默认无法序列化它们,加载时会提示 ValueError: Unknown layer 或 AttributeError: 'NoneType' object has no attribute 'name'。
立即学习“Python免费学习笔记(深入)”;
- 解决方法:保存时加
custom_objects参数 —— 但注意,tf.saved_model.save**本身不接受**custom_objects参数,这是model.save(..., save_format="h5")的用法 - 正确做法是:改用
tf.keras.models.save_model并指定save_format="tf",同时传入custom_objects:tf.keras.models.save_model( model, "./my_custom_model", save_format="tf", custom_objects={"MyCustomLayer": MyCustomLayer} ) - 或者,在自定义类中实现
get_config()和from_config(),并确保类在加载环境里已定义(推荐)
tf.saved_model 格式不保存训练状态(optimizer weights)除非显式要求
默认情况下,tf.saved_model.save 只保存模型结构和参数(trainable_variables),不保存 optimizer 的内部状态(比如 Adam 的 m、v)。所以加载后不能直接 model.fit() 接续训练。
- 若需恢复训练:保存前确保模型已编译,并传入
include_optimizer=True(仅对tf.keras.models.save_model有效) -
tf.saved_model.save不支持include_optimizer,所以必须用tf.keras.models.save_model(..., save_format="tf") - 检查是否保存了 optimizer:加载后运行
loaded.optimizer,若为None就说明没存;也可以看保存目录下是否有variables/variables.index之外的 optimizer 相关文件(通常没有)
最易被忽略的是:签名(signature)和自定义对象的加载环境一致性。哪怕只差一个类定义位置或版本,tf.saved_model.load 都可能静默失败或在调用时才抛异常。


















