【问题标题】:Cannot load protocol buffer with ReadBinaryProto Tensorflow无法使用 ReadBinaryProto Tensorflow 加载协议缓冲区
【发布时间】:2018-08-14 13:58:35
【问题描述】:

我在加载从 C++ 中的 tensorflow 模型保存的协议缓冲区文件时遇到问题。我可以毫无问题地在 Python 中加载和执行 .pb 文件,但是当尝试使用 ReadBinaryProto 函数在 C++ 中加载它时出现错误:

String field'tensorflow.MetaGraphDef.MetaInfoDef.tensorflow_version' 
   contains invalid UTF-8 data when parsing a protocol buffer. Use the 'bytes' 
   type if you intend to send raw bytes.

   Non-OK-status: LoadModel(session_inception, pathToGraph ) status: Data loss: 
   Can't parse E:/Projects/SampleTensorflow/tmp/latestmodel.pb as binary proto

我正在使用 Tensorflow v1.10,下面发布了一个 C++ 代码示例,我尝试了许多不同的方法来保存 .pb 文件,包括使用 freeze_graph 方法和 tf.write_graph方法,似乎都无法解决问题。

  tensorflow::Status LoadModel(tensorflow::Session *sess, std::string 
  graph_fn, std::string checkpoint_fn = "") {
  tensorflow::Status status;

  std::string graph_fn = "E:/Projects/SampleTensorflow/tmp/latestmodel.pb";      

  // Read in the protobuf graph
  tensorflow::MetaGraphDef graph_def;
  status = ReadBinaryProto(tensorflow::Env::Default(), graph_fn, 
                            &graph_def);

  if (status != tensorflow::Status::OK())
    return status;

  // Create the graph
  status = sess->Create(graph_def.graph_def());
  if (status != tensorflow::Status::OK())
      return status;

感谢您的帮助!

【问题讨论】:

  • 警告:你使用的是和 TF 一样的 protobuf 版本吗?
  • protobuf 文件随 TF 的安装一起提供,所以我假设我会这样做,除非我必须以某种方式单独安装它们?
  • 您确定 pb 包含 MetaGraphDef 而不是 GraphDef?用python怎么读?
  • @P-Gn Doh!我相当确定该图是作为 GraphDef 而不是 MetaGraphDef 导出的。我现在将尝试更新 C++ 代码以适应这种情况,或者是否有更简单的方法来导出 MetaGraphDef?
  • 我认为使用MetaGraphDefs 的首选方式实际上是通过SavedModelBundles。它相当容易使用,但需要对您的代码进行更多更改。

标签: c++ tensorflow protocol-buffers


【解决方案1】:

一个可能的错误是.pb 文件包含GraphDef 而不是MetaGraphDef

要阅读GraphDef,只需切换到

tensorflow::GraphDef graph_def;
status = ReadBinaryProto(tensorflow::Env::Default(), graph_fn, 
                        &graph_def);

protobuf 格式确实只是一个容器,它没有说明它包含什么。在 tensorflow 中,这种格式通常用于包含图和元图,这可能会造成混淆。

【讨论】:

  • 只是要补充一点,我注意到 .pb 文件现在已初始化,但似乎没有给出正确的输出预测与“未初始化的 3 个元素的张量”。这是因为需要元数据才能正确使用它,尽管在 python 中我似乎能够仅使用 .pb 文件做出准确的预测。再次感谢
  • 如果您的图表仍然包含变量,那么SavedModelBundles 是打包所有内容的好方法。当您冻结图表时,简单的图表仍然很有用,将所有变量转换为常量。在这些情况下,绝不需要元数据。
  • 几天来有同样的问题,由于这个答案终于解决了。真的很感激!
猜你喜欢
  • 1970-01-01
  • 2011-09-18
  • 1970-01-01
  • 1970-01-01
  • 2019-09-21
  • 2021-12-19
  • 2011-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多