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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:25:05