使用 protoc 读取 Google Protocol Buffer (.pb) 文件

4
我已经从源代码编译了Google Protobuf并生成了protoc二进制文件。现在,假设有一个.pb文件,即tensorflow_inception_v3_stripped_optimized_quantized.pb,我该如何在不使用Tensorflow库的情况下读取它的内容?
目前,我可以编写一个示例读取器来转储我的.pb文件的事件,稍后可以通过以下方式由tensorboard读取:
import tensorflow as tf
from tensorflow.python.platform import gfile

INCEPTION_LOG_DIR = '/tmp/inception_v3_log'

if not os.path.exists(INCEPTION_LOG_DIR):
    os.makedirs(INCEPTION_LOG_DIR)
with tf.Session() as sess:
    model_filename = './model/tensorflow_inception_v3_stripped_optimized_quantized.pb'
    with gfile.FastGFile(model_filename, 'rb') as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())
        _ = tf.import_graph_def(graph_def, name='')
    #writer = tf.train.SummaryWriter(INCEPTION_LOG_DIR, graph_def)
    writer=tf.summary.FileWriter(INCEPTION_LOG_DIR, graph_def)                                                
    writer.close()

然而,我不太明白我为什么要编译protoc?它不能作为独立的阅读器使用吗?或者,在Tensorflow的后端中,所提到的inception.pb文件已经在使用Protocol buffer,而无需使用protoc吗?

像这样的命令确实会生成错误:

protoc --python_out=. tensorflow_inception_v3_stripped_optimized_quantized.pb
protoc --cpp_out=. tensorflow_inception_v3_stripped_optimized_quantized.pb

我查看了一下,.pb 文件是半可读的,但是我无法在任何地方找到直接解析该文件内容的坚实答案。我是否遗漏了什么?谢谢。


protoc(以及一系列第三方工具)可用于在广泛的语言/框架中生成代码;大多数protobuf使用与tensorflow 没有任何关系;涉及的确切API取决于您感兴趣的语言/框架。那么:您想使用什么语言/框架?您提到“这些命令会生成错误:”-但是:该命令需要一个.proto模式,而不是数据文件。 protoc 可以解释数据文件,但这不是通常的用法。您是否有模式文件? - Marc Gravell
具体而言,使用 protoc 处理数据文件有两种方式 - 一种涉及 .proto 文件和数据文件,另一种只涉及数据文件但结果不够清晰;也许都不是你想要的方式... - Marc Gravell
1
你可能需要“管道”输入(stdin) - 或者只需尝试我的网站 :) - Marc Gravell
@MarcGravell,我想知道您是否能够建议一种使用.proto解码文件的方法,这个命令不起作用:protoc --decode MSG --proto-path=/PATH/TO/PROTOs file.proto < frozen_PBfile.pb 预先感谢您! - Amir
定义 "this doesn't work" - 会发生什么? - Marc Gravell
显示剩余4条评论
1个回答

7

是的,protoc也可以用来解码 .pb 文件。

protoc --decode_raw < my_input.pb

将输出文件的原始结构。这并不是很有用,因为(与XML或JSON相反)protobuf文件不包含太多结构信息(元素名称),但这些信息被“外包”到.proto文件中。

如果您拥有正确的.proto文件,例如来自tensorflow存储库的文件,则可以使用-I path_to_tensorflow_checkout并指定正确的消息类型名称。请注意,在tensorflow .proto文件中,所有类型都在tensorflow包中,因此您必须添加前缀来指定类型名称。以下是一个工作示例:

protoc --decode tensorflow.SavedModel tensorflow/core/protobuf/saved_model.proto < path_to_saved_model.pb

在这种情况下,我从tensorflow存储库目录中运行了命令,省略了-I / --proto_path
根据您的模型文件格式(SavedModel或GraphDef),您可能需要使用tensorflow.GraphDef(例如,“冻结图”)而不是tensorflow.SavedModel

我正在TF存储库中,并使用protoc --decode tensorflow.SavedModel tensorflow/core/protobuf/saved_model.proto < ~/tensorflow_inception_v3_stripped_optimized_quantized.pb命令,但只得到了“无法解析输入”的错误信息。 - Amir
@Amir,decode_raw 能用吗?这样我们就可以检查它是否是有效的 .pb 文件。 - hans_meine
是的,它可以解码.pb文件的结构(树形),但我想看到权重和其他参数的值。 - Amir
是的,我只是想帮助调试您的问题。奇怪的是,因为您的命令看起来很好,这就是它对我有用的方式。您确定您拥有一个SavedModel而不是GraphDef吗?这可能与TF版本有关吗?(我猜不会,因为您可能已经进行了最新的检查。) - hans_meine
实际上,这是谷歌在2015年末推出的旧版inception-v3的冻结.pb文件。您可以在此处自行查看:https://storage.googleapis.com/download.tensorflow.org/models/tensorflow_inception_v3_stripped_optimized_quantized.pb - Amir
是的,你需要使用 tensorflow.GraphDef 而不是 tensorflow.SavedModel;我尝试了一下并得到了期望的结果。 - hans_meine

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