TensorFlow中freeze_graph.py使用方法及Unity .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

