tensorflow.net 当前(v2.14+)不支持直接加载 savedmodel,loadsavedmodel() 抛 notimplementedexception;正确做法是传入含 saved_model.pb 和 variables/ 的目录路径,并通过 python 查 signature 后按签名张量名调用。

用 TensorFlow.NET 加载 SavedModel 会直接报错“NotImplementedException”
因为 TensorFlow.NET 当前(v2.14+)对 SavedModel 的原生支持仍不完整,LoadSavedModel() 函数只是声明了,但底层没实现——调用就崩。这不是你模型导出有问题,是库本身卡在关键路径上。
实操建议:
- 改用
TensorFlowSharp?不行,它已停止维护,且不支持 TF 2.x 的SavedModel格式 - 真正可行的路只有一条:把
SavedModel转成.pb冻结图(frozen graph),再用TensorFlow.NET的Session.LoadFromSavedModel()替代方案——即Session.LoadMetaGraph()+Session.Restore(),但这要求你有.meta+.index+.data三件套 - 更稳的选择:用 Python 启一个轻量服务(比如 Flask +
tf.keras.models.load_model()),C# 通过 HTTP 调用;或者用ML.NET做中间桥接(前提是模型结构能被 ML.NET 导入)
SavedModel 目录里一堆文件,C# 到底该读哪个路径?
别碰 variables/ 或 assets/ 单独路径——TensorFlow.NET 的 LoadSavedModel() 期望的是整个目录的**父路径**,且该路径下必须包含 saved_model.pb(或 saved_model.pbtxt)和 variables/ 子目录。
常见错误现象:
- 传入
"./mymodel/variables"→ 报Invalid argument: Expected model file at .../variables/saved_model.pb - 传入
"./mymodel/saved_model.pb"(文件路径)→ 报DirectoryNotFoundException - 路径末尾带斜杠或不带斜杠,行为不一致;建议统一用
Path.GetFullPath()规范化
正确写法示例:
string modelPath = Path.GetFullPath(@"..\models\my_tf2_model"); // 指向含 saved_model.pb 的目录 var session = Session.LoadFromSavedModel(modelPath); // 注意:此行目前会抛 NotImplementedException
输入输出张量名对不上,session.GetOutput() 返回空或 shape 不匹配
TF 2.x 的 SavedModel 默认用的是“signature def”,不是原始 tensor 名。C# 侧看不到 serving_default 这类 signature,直接按 "input:0" 硬写大概率失败。
必须先查签名:
- 用 Python 快速确认:
from tensorflow.saved_model import load; m = load("path"); list(m.signatures.keys()),通常返回['serving_default'] - 再看输入输出:
m.signatures['serving_default'].structured_input_signature - C# 中不能跳过这步——你得把 signature 里的
input_1:0、output_1:0这类名字抄下来,而不是猜 -
Session.Run()时,feed dict 的 key 必须是 signature 中的 tensor name(含冒号),例如"serving_default_input_1:0",不是"input_1"
为什么不用 ML.NET 直接加载 SavedModel?
ML.NET 的 TensorFlowModelScorer 确实支持 SavedModel,但它只认 TF 1.x 风格的模型(即含 .meta 文件的 checkpoint),对 TF 2.x 的纯 SavedModel(只有 saved_model.pb + variables/)支持有限,容易在 LoadTensorFlowModel() 时抛 InvalidOperationException: Could not find SavedModel bundle。
如果你的模型是 Keras 训练的,更现实的做法是:
- 导出时加
signatures参数,确保 signature 名明确、输入输出 tensor 名不含动态前缀 - 在 C# 中放弃“全自动加载”,改用
TensorFlow.NET手动构造Graph+Session,并显式指定 placeholder 和 fetch node - 接受一个事实:C# 生态对 TF 2.x 模型的原生支持仍是补丁状态,绕不开 Python 辅助验证和转换
最常被忽略的一点:TF 版本锁死。C# 项目引用的 TensorFlow.NET 必须与训练环境的 TensorFlow 主版本一致(比如 TF 2.12 训练 → C# 必须用 TensorFlow.NET v2.12.x),否则 saved_model.pb 解析会静默失败,连错误都不报全。










