“frozen_inference_graph.pb”和“saved_model.pb”的区别是什么?

38
我有一个使用 Faster R-CNN 训练的模型,使用 export_inference_graph.py 导出进行推理。我想要了解创建的 frozen_inference_graph.pbsaved_model.pb 以及 model.ckpt* 文件之间的区别。我还看到了 .pbtxt 的表示形式。
我尝试阅读了此链接,但没有找到答案:https://www.tensorflow.org/extend/tool_developers/ 这些文件包含什么内容? 哪些文件可以转换为其他文件? 每个文件的理想目的是什么?
2个回答

58

frozen_inference_graph.pb是一个冻结的图,不能再进行训练,它定义了图形定义,并且实际上是一个序列化的图形,可以使用以下代码加载:

frozen_inference_graph.pb是一个冻结的图,不能再进行训练,它定义了图形定义,并且实际上是一个序列化的图形,可以使用以下代码加载:

def load_graph(frozen_graph_filename):
    with tf.gfile.GFile(frozen_graph_filename, "rb") as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())
        return graph_def
tf.import_graph_def(load_graph("frozen_inference_graph.pb"))

保存的模型是由tf.saved_model.builder生成的模型,必须导入到会话中。该文件包含完整的图形,包括所有训练权重(就像冻结的图形),但可以在此进行训练,而且它没有序列化并需要通过此片段加载。[]是可以被saved_model_cli读取的标签常数。这个模型通常也用于预测,例如Google ML引擎:

with tf.Session() as sess:
    tf.saved_model.loader.load(sess, [], "foldername to saved_model.pb, only folder")

model.ckpt文件是在训练期间生成的检查点,可用于恢复训练或在长时间训练后出现问题时备份。如果您有一个保存的模型和一个冻结的图,则可以忽略此文件。

.pbtxt文件基本上与先前讨论的模型相同,但可读性更强,不是二进制的。这些也可以被忽略。

回答您的转换问题:

保存的模型可以转换为冻结的图,反之亦然,虽然从冻结的图中提取的saved_model也无法进行训练,但它存储的方式是saved_model格式。检查点可以被读入并加载到会话中,在那里您可以从中构建一个saved_model。

希望我有所帮助,如有任何问题,请随时问我!

补充说明:

如何从保存的模型文件夹结构开始冻结图。 这篇文章旧了,所以我以前使用的方法可能不再适用,但最可能仍然适用于Tensorflow 1.+。

首先从tensorflow库中下载此文件,然后这段代码片段应该就可以解决问题:

    import freeze_graph # the file you just downloaded
    from tensorflow.python.saved_model import tag_constants # might be unnecessary

    freeze_graph.freeze_graph(
        input_graph=None,
        input_saver=None,
        input_binary=None,
        input_checkpoint=None,
        output_node_names="dense_output/BiasAdd",
        restore_op_name=None,
        filename_tensor_name=None,
        output_graph=os.path.join(path, "frozen_graph.pb"),
        clear_devices=None,
        initializer_nodes=None,
        input_saved_model_dir=path,
        saved_model_tags=tag_constants.SERVING
    )

输出节点名称 = 最终操作的节点名称,如果您在密集层上结束,则为dense layer_name/BiasAdd。

输出图形 = 输出图形的名称。

输入saved_model_dir = 保存模型的根文件夹。

saved_model_tags = 保存模型的标签,在您的情况下可以是None,但我使用了一个标签。

另外需要注意的是:

加载模型的代码已经在上面提供了。要进行预测,您需要会话(session)。对于保存的模型,此会话已经创建;对于冻结的模型,则没有。

保存的模型:

with tf.Session() as sess:
    tf.saved_model.loader.load(sess, [], "foldername to saved_model.pb, only folder")
    prediction = sess.run(output_tensor, feed_dict={input_tensor: test_images})

冻结模型:

tf.import_graph_def(load_graph("frozen_inference_graph.pb"))
with tf.Session() as sess:
    prediction = sess.run(output_tensor, feed_dict={input_tensor: test_images})

要进一步了解您的输入和输出层是什么,您需要使用TensorBoard查看它们,只需将以下代码行添加到会话中:

tf.summary.FileWriter("path/to/folder/to/save/logs", sess.graph)

这行代码将创建一个日志文件,您可以在cli/powershell中打开它,要了解如何运行tensorboard,请查看此以前发布的问题


1
感谢 @"T. Kelher" 的回答。为什么在Cloud ML中使用 saved_model.pb 进行预测更好呢?毕竟 frozen_inference.graph.pb 可能更小,而且此时你已经不再进行训练了。我假设你可以从 saved_model.pb 生成 frozen_inference_graph.py,但不能反过来。 - nickponline
1
首选项不是正确的术语,更精确是唯一可接受的方式,Google ML引擎不接受冻结图。转换可以双向进行,从冻结图构建的保存模型仍然可以正常工作,只是不能再进行训练了。 - T. Kelher
我已经有一个保存的模型格式(包含资产、变量和saved_model.pb的目录)。如何将其转换为冻结图(一个单独的file.pb)? - fisakhan
@Fisa 请看我在答案中添加的附加部分。 - T. Kelher
@"Parth Tamane" 我进行了编辑,希望这样能更清晰明了。 - T. Kelher
显示剩余2条评论

6

需要补充的是,frozen_graph.pb包括两个部分: 1. 图定义 2. 训练参数

而save_model.pb只有图定义。

这就是为什么如果你检查两个.pb文件的大小,frozen_graph.pb总是更大的原因。


所以,基本上,.pb文件的结构是相同的,我可以使用tf.saved_model.load技术上加载frozen_model.pb,对吗? - Chan Kha Vu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接