keras的model.save()保存的是含python层逻辑和未冻结变量的savedmodel,非纯tensorflow原生图;需显式导出savedmodel并获取concretefunction,或用tf.function+get_concrete_function生成冻结图。

不能直接用 Keras 的 model.save() 得到纯 TensorFlow 原生图模型(即不含 Keras 层封装、无 Python 依赖的 tf.Graph 或 SavedModel 冻结图)——必须显式导出为 SavedModel 并可选地冻结变量。
为什么 model.save('path') 不等于原生图模型?
Keras 默认保存的是包含 Python 层逻辑、自定义对象引用和未冻结变量的 SavedModel,加载时仍需 tf.keras 运行时支持。它不是“纯图”:变量仍是可变的,控制流可能含 eager 模式痕迹,且无法被 TFLite、TensorRT 或 C++ TF API 直接消费。
要获得真正脱离 Keras 的原生图,关键动作是:导出为 SavedModel → 再用 tf.saved_model.load() 加载 → 调用具体 signature 获取 ConcreteFunction → 导出为冻结图(如需)或直接使用 SavedModel。
导出纯静态图:用 tf.function + get_concrete_function
这是最可控的方式,能生成不含变量、全为常量节点的图(即传统“frozen graph”),适合部署到无 Python 环境。
- 必须先确保模型已 build(有 input_shape),否则
get_concrete_function会失败 - 输入签名需明确指定 shape 和 dtype,例如:
input_spec = tf.TensorSpec(shape=[None, 224, 224, 3], dtype=tf.float32) - 调用
model.__call__或自定义前向函数(不能用model.predict)并用@tf.function包裹 - 再调用
concrete_func = func.get_concrete_function(input_spec) - 最后用
tf.io.write_graph(concrete_func.graph, 'path', 'model.pb', as_text=False)写二进制图(注意:此图不含变量,仅结构;若需含权重,应走 SavedModel 路径)
更推荐的路径:导出标准 SavedModel 并禁用 Keras 痕迹
现代 TF 部署(如 TF Serving、TFLite Converter)都基于 SavedModel,而非旧式 frozen pb。关键是让 SavedModel “去 Keras 化”:
仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...
- 避免在模型中使用
tf.keras.layers.Lambda或自定义 Python 函数,它们会引入py_func节点 - 用
tf.keras.models.clone_model(model, clone_function=...)替换掉含 Python 逻辑的层(如有) - 保存时传入
signatures参数,例如:tf.saved_model.save(model, 'export_dir', signatures={'serving_default': model.call.get_concrete_function(input_spec)}) - 保存后检查:
saved_model_cli show --dir export_dir --all,确认 signatures 下没有keras_api字样,且 inputs 是 tensor spec 而非 dict-of-tensors
常见报错与绕过方式
ValueError: Cannot convert a symbolic Tensor to a numpy array:说明你在 @tf.function 外调用了 .numpy() 或类似操作,删掉或移到 function 外。
NotImplementedError: Cannot convert a symbolic Tensor:多见于用 tf.keras.backend.eval() 或 model.layers[i].output 直接取输出,改用 model(inputs) 或 model.call(inputs)。
KeyError: 'saved_model' not found in checkpoint:用 tf.train.Checkpoint 手动保存时路径写错,应确保 checkpoint.write(path) 的 path 不带扩展名,且与 tf.saved_model.load() 的目录一致。
最易忽略的一点:Keras 模型若含 tf.keras.layers.Resizing 或 tf.keras.layers.RandomFlip 等预处理层,导出后仍会保留这些 ops —— 它们不是纯计算图的一部分,部署时需前置剥离或替换为 tf.image 原语。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










