You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用TensorFlowSharp从C#加载PB模型时遇未初始化变量错误

解决TensorFlowSharp加载PB模型时"Attempting to use uninitialized value Variable"错误

你遇到的问题根源很明确:你用tf.train.write_graph导出的PB文件只保存了TensorFlow图的结构定义,没有包含训练后变量(比如逻辑回归的权重W、偏置b)的实际值。当你在C#里加载这个模型时,图里的变量还是处于未初始化的状态,自然会抛出这个错误。

下面给你两种可行的解决方案,任选其一即可:

方案1:导出包含变量值的SavedModel格式(推荐)

SavedModel是TensorFlow官方推荐的跨语言模型格式,它同时包含图结构和变量参数,TensorFlowSharp对这个格式的支持很完善。

Python端导出代码

import tensorflow as tf

# 假设你的逻辑回归模型定义和训练代码在这里
# 示例模型定义:
x = tf.placeholder(tf.float32, shape=[None, 1], name="input_x")
y_true = tf.placeholder(tf.float32, shape=[None, 1], name="input_y")
W = tf.Variable(tf.random_normal([1,1]), name="weights")
b = tf.Variable(tf.zeros([1]), name="bias")
y_pred = tf.sigmoid(tf.matmul(x, W) + b, name="output_pred")

# (省略训练过程:优化器定义、会话运行训练的代码)

# 训练完成后,导出SavedModel
builder = tf.saved_model.builder.SavedModelBuilder("./logistic_model")
# 定义输入输出签名,方便跨语言调用
signature_def = tf.saved_model.signature_def_utils.predict_signature_def(
    inputs={"input_x": x},
    outputs={"output_pred": y_pred}
)
builder.add_meta_graph_and_variables(
    sess,
    [tf.saved_model.tag_constants.SERVING],
    signature_def_map={
        tf.saved_model.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: signature_def
    }
)
builder.save()

C#端加载代码

using (var session = new TFSession())
{
    // 加载SavedModel,"serve"是默认的服务标签
    var model = session.LoadModel("./logistic_model", new[] { "serve" }, null);
    var runner = session.GetRunner();
    
    // 准备输入数据(这里假设你将CSV转为float二维数组)
    float[,] inputData = LoadCsvAsFloatArray("dataX.csv", 1);
    runner.AddInput(model.Graph["input_x"][0], inputData);
    runner.Fetch(model.Graph["output_pred"][0]);
    
    // 运行预测并获取结果
    var results = runner.Run();
    var predictions = (float[,])results[0].GetValue();
}

方案2:将变量转换为常量后导出PB文件

如果你坚持要使用PB格式,可以把训练后的变量转换成图中的常量节点,这样导出的PB文件就包含了所有参数值,加载后不需要初始化变量。

Python端导出代码

import tensorflow as tf
from tensorflow.python.framework import graph_util

# (省略模型定义与训练代码)

# 训练完成后,将变量转换为常量
graph_def = tf.get_default_graph().as_graph_def()
# 必须指定模型的输出节点名称,TensorFlow会自动把依赖的变量转为常量
output_graph_def = graph_util.convert_variables_to_constants(
    sess,
    graph_def,
    ["output_pred"]  # 替换为你自己模型的输出节点名称
)

# 保存转换后的PB文件
with tf.gfile.GFile("./logistic-sigmoid-cpm-model.pb", "wb") as f:
    f.write(output_graph_def.SerializeToString())

C#端加载代码

var modelBytes = File.ReadAllBytes("logistic-sigmoid-cpm-model.pb");
var graph = new TFGraph();
graph.Import(modelBytes, "");

using (var session = new TFSession(graph))
{
    var runner = session.GetRunner();
    float[,] inputData = LoadCsvAsFloatArray("dataX.csv", 1);
    // 输入节点名要和Python里定义的一致,比如"input_x"
    runner.AddInput(graph["input_x"][0], inputData);
    // 输出节点名对应Python里指定的"output_pred"
    runner.Fetch(graph["output_pred"][0]);
    
    var results = runner.Run();
    var predictions = (float[,])results[0].GetValue();
}

关键注意事项

  • 不管用哪种方案,一定要确保Python端导出时的节点名称(输入、输出、变量名)和C#端引用的名称完全一致,否则会出现找不到节点或参数不匹配的错误。
  • 方案2中,转换常量时必须指定正确的输出节点名称,否则TensorFlow不会自动把所有依赖的变量都转换成常量。

内容的提问来源于stack exchange,提问作者Joseph Wu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:54:46