Unity导入Keras/TensorFlow模型推理时遇TFException未初始化值问题
解决Unity中TensorFlow模型推理时“未初始化变量”的异常问题
你碰到的这个问题在Keras模型导入Unity时挺常见的,核心原因是导出的模型里还保留着未转换为常量的变量节点,或者Unity加载时没处理变量初始化逻辑。我给你梳理下具体的解决步骤:
第一步:导出固化后的TensorFlow模型(Frozen Graph)
Keras默认保存的.h5模型是把结构和权重分开存储的,里面还保留着action_W这类变量节点,而Unity的TensorFlowSharp更适配所有变量都转为常量的固化.pb模型。你可以用下面的Python代码把Keras模型转成固化版本:
import tensorflow as tf from tensorflow.keras.models import load_model # 加载你训练好的Keras模型 model = load_model("your_trained_model.h5") # 获取你在Unity中验证过的输入输出节点名称(去掉名称末尾的":0") input_node_name = model.input.name.split(':')[0] output_node_name = model.output.name.split(':')[0] # 定义固化模型的工具函数 def freeze_keras_model(session, output_names): from tensorflow.python.framework.graph_util import convert_variables_to_constants graph_def = convert_variables_to_constants( session, session.graph.as_graph_def(), output_names=output_names ) return graph_def # 获取Keras会话并执行固化 sess = tf.keras.backend.get_session() frozen_graph = freeze_keras_model(sess, [output_node_name]) # 保存固化后的模型文件 tf.train.write_graph(frozen_graph, "./", "frozen_model.pb", as_text=False)
这段代码会把模型里所有的变量(比如action_W)转换成常量,Unity加载后就不会出现未初始化的问题了。
第二步:在Unity中加载固化模型并执行推理
把生成的frozen_model.pb放到Unity的Assets目录下(推荐放在StreamingAssets里),然后用类似下面的代码完成加载和推理:
using System.IO; using TensorFlow; using UnityEngine; public class TFModelInference : MonoBehaviour { private TFGraph _graph; private TFSession _session; // 替换成你自己的输入输出节点名称 private const string InputNodeName = "your_input_node_name"; private const string OutputNodeName = "your_output_node_name"; void Start() { // 加载固化模型 string modelPath = Path.Combine(Application.streamingAssetsPath, "frozen_model.pb"); _graph = new TFGraph(); _graph.Import(File.ReadAllBytes(modelPath)); // 创建TensorFlow会话 _session = new TFSession(_graph); } public float[] RunInference(float[] inputData) { // 准备输入张量(形状要和模型输入维度匹配) var inputTensor = TFTensor.FromBuffer( TFDataType.Float, new long[] {1, inputData.Length}, // 这里假设批量大小为1,输入维度根据你的模型调整 inputData, 0, inputData.Length * sizeof(float) ); // 执行推理 var runner = _session.GetRunner(); runner.AddInput(_graph[InputNodeName][0], inputTensor); runner.Fetch(_graph[OutputNodeName][0]); var outputs = runner.Run(); var result = outputs[0].GetValue() as float[,]; // 整理结果并返回 float[] outputArray = new float[result.GetLength(1)]; for (int i = 0; i < result.GetLength(1); i++) { outputArray[i] = result[0, i]; } return outputArray; } }
额外注意事项
- 确认Unity中使用的输入输出节点名称和固化模型里的完全一致(可以用TensorBoard打开固化模型查看节点结构)
- 替换掉旧的未固化模型,确保Unity加载的是新生成的
.pb文件 - 可以先在Python中加载固化模型测试推理,确认模型本身没有问题再导入Unity
这样应该就能解决你遇到的TFException: Attempting to use uninitialized value异常了。
内容的提问来源于stack exchange,提问作者Bah_0
相关产品推荐
相关产品推荐

