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

TensorFlow中freeze_graph.py使用方法及Unity .bytes文件问题求助

解决TensorFlow冻结模型用于Unity的两个问题:TypeError与.bytes文件生成方案

我来帮你搞定这两个困扰你的问题——先拆解那个TypeError的根源,再给你几个不用freeze_graph.py就能生成Unity兼容.bytes文件的实用方案。

一、先解决TypeError: names_to_saveables must be a dict...报错

这个错误的核心原因很明确:你调用freeze_graph.freeze_graph时,传入的names_to_saveables参数要求是字符串到TensorFlow Variable(可训练变量)的字典映射,但你传入的是一个Tensor(比如报错里的BoxPredictor_0/BoxEncodingPredictor/biases:0),而不是Variable。

快速修复步骤:

  • 先核对你要冻结的节点是否真的是可训练变量:用tf.train.list_variables("你的checkpoint文件路径")列出 checkpoint 中所有的可训练变量,确保你指定的节点名字在这个列表里。如果不在,说明这个节点是计算生成的Tensor,不是可保存的变量,不能通过names_to_saveables指定。
  • 如果你确实需要包含这个Tensor,建议放弃freeze_graph.py,改用下面提到的TensorFlow原生API手动冻结,这种方式更灵活,能自动处理变量转常量的逻辑。
  • 检查output_node_names参数:确保你指定的输出节点是模型实际的推理输出节点,名字写错也会导致类似的匹配错误。

二、不用freeze_graph.py生成Unity可用的.bytes文件

Unity要求的.bytes本质就是二进制文件,只要是正确冻结的TensorFlow模型二进制内容,不管后缀是.pb还是.bytes,Unity都能识别(甚至直接把.pb重命名为.bytes就能用)。下面给你几个更可靠的替代方案:

方案1:用TensorFlow原生API手动冻结并保存为二进制

这个方法绕过freeze_graph.py,直接用TensorFlow的convert_variables_to_constants API把变量转为常量,生成的二进制文件可以直接保存为.bytes:

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

# 1. 加载你的模型(这里以SavedModel格式为例,也可以用ckpt加载)
with tf.compat.v1.Session() as sess:
    # 加载SavedModel
    tf.compat.v1.saved_model.loader.load(sess, ["serve"], "你的SavedModel路径")
    
    # 2. 指定模型的输出节点(根据你的模型调整,比如检测模型的输出可能是boxes、scores等)
    output_node_names = ["BoxPredictor_0/BoxEncodingPredictor/BiasAdd", "BoxPredictor_0/ClassPredictor/BiasAdd"]
    
    # 3. 把变量转换为常量,生成冻结图
    frozen_graph_def = graph_util.convert_variables_to_constants(
        sess,
        sess.graph_def,
        output_node_names
    )
    
    # 4. 保存为.bytes文件
    with open("frozen_model.bytes", "wb") as f:
        f.write(frozen_graph_def.SerializeToString())

这个方法能避免freeze_graph.py的参数限制,更适合复杂模型的冻结。

方案2:转换为TensorFlow Lite格式再存为.bytes

如果你的Unity项目使用TensorFlow Lite插件,这个方案更高效——TFLite模型体积更小,运行更快,而且直接保存为二进制后重命名为.bytes即可:

import tensorflow as tf

# 加载SavedModel并转换为TFLite
converter = tf.lite.TFLiteConverter.from_saved_model("你的SavedModel路径")
# 如果需要支持自定义操作,添加converter.target_spec.supported_ops = [...]
tflite_model = converter.convert()

# 保存为.bytes文件
with open("model.tflite.bytes", "wb") as f:
    f.write(tflite_model)

在Unity中,你可以用TensorFlow Lite插件直接加载这个.bytes文件,无需额外处理。

方案3:直接重命名已有的.pb文件

如果你已经成功生成了正确的冻结.pb文件,最简单的方法就是直接把它的后缀改成.bytes——Unity会把它识别为二进制TextAsset,加载时读取其bytes属性即可传入TensorFlow插件。

最后补充Unity加载小提示

在Unity中,把.bytes文件导入后,设置其Import Settings为TextAsset,然后通过代码读取:

TextAsset modelAsset = Resources.Load<TextAsset>("frozen_model");
// 把bytes传给TensorFlow插件加载模型

内容的提问来源于stack exchange,提问作者matthew hallberg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:53:38