【问题标题】:TensorFlow freeze_graph.py: The name 'save/Const:0' refers to a Tensor which does not existTensorFlow freeze_graph.py:名称“save/Const:0”指的是不存在的张量
【发布时间】:2019-09-02 21:33:17
【问题描述】:

我目前正在尝试将经过训练的 TensorFlow 模型导出为 ProtoBuf 文件,以便在 Android 上将其与 TensorFlow C++ API 一起使用。因此,我使用的是freeze_graph.py 脚本。

我使用tf.train.write_graph 导出了我的模型:

tf.train.write_graph(graph_def, FLAGS.save_path, out_name, as_text=True)

我正在使用通过tf.train.Saver 保存的检查点。

我调用freeze_graph.py,如脚本顶部所述。编译后,我运行

bazel-bin/tensorflow/python/tools/freeze_graph \
--input_graph=<path_to_protobuf_file> \
--input_checkpoint=<model_name>.ckpt-10000 \
--output_graph=<output_protobuf_file_path> \
--output_node_names=dropout/mul_1

这给了我以下错误信息:

TypeError: Cannot interpret feed_dict key as Tensor: The name 'save/Const:0' refers to a Tensor which does not exist. The operation, 'save/Const', does not exist in the graph.

由于错误状态,我的导出模型中没有张量 save/Const:0。但是,freeze_graph.py 的代码表示可以通过标志 filename_tensor_name 指定此张量名称。不幸的是,我找不到关于这个张量应该是什么以及如何为我的模型正确设置它的任何信息。

谁能告诉我如何在导出的 ProtoBuf 模型中生成 save/Const:0 张量或如何正确设置标志 filename_tensor_name?

【问题讨论】:

    标签: python tensorflow protocol-buffers


    【解决方案1】:

    --filename_tensor_name 标志用于指定在为模型构造 tf.train.Saver 时创建的占位符张量的名称。*

    在您的原始程序中,您可以打印出saver.saver_def.filename_tensor_name 的值以获取您应该为该标志传递的值。您可能还想打印saver.saver_def.restore_op_name 的值以获取--restore_op_name 标志的值(因为我怀疑默认值不适合您的图表)。

    或者,tf.train.SaverDef protocol buffer 包含重建这些标志的相关信息所需的所有信息。如果您愿意,可以将saver.saver_def 写入文件,并将该文件的名称作为--input_saver 标志传递给freeze_graph.py。


     * tf.train.Saver 的默认名称范围是 "save/",占位符是 actually a tf.constant(),其名称默认为 "Const:0",这就解释了为什么标志默认为 "save/Const:0"。

    【讨论】:

      【解决方案2】:

      我注意到当我按如下方式排列代码时发生了错误:

      sess = tf.Session()
      tf.train.write_graph(sess.graph_def, '', '/tmp/train.pbtxt')
      init = tf.initialize_all_variables()
      saver = tf.train.Saver()
      sess.run(init)
      

      在我像这样更改代码布局后它起作用了:

      # Add ops to save and restore all the variables.
      saver = tf.train.Saver()    
      init = tf.initialize_all_variables()
      sess = tf.Session()
      tf.train.write_graph(sess.graph_def, '', '/tmp/train.pbtxt')
      sess.run(init)
      

      我不太确定这是为什么。 @mrry 你能解释一下吗?

      【讨论】:

      • +1 有同样的问题,以与你写的完全相同的方式更改行顺序,也为我解决了这个问题。也希望得到一些澄清:)
      • 似乎saver 需要在sess 之外才能在不同的会话中重复使用。
      【解决方案3】:

      对@Drag0 的回答以及新代码布局修复错误的原因进行了一些跟进。

      在调用saver = tf.train.Saver() 时,将与tf.train.Saver() 相关的不同变量(例如'save/Const:0')添加到默认图表中。

      在第一个代码排列中,图形在之前保存,因此没有tf.train.Saver() 变量。在第二个代码排列之后它被保存,因此操作save/Const将存在于图中。

      【讨论】:

        【解决方案4】:

        在最新的 freeze_graph.py 中应该没有问题,因为我可以看到这些被删除:

        del restore_op_name, filename_tensor_name # Unused by updated loading code. source:freeze_graph.py

        在早期版本中,它是使用 restore_op 来恢复模型的

        sess.run([restore_op_name], {filename_tensor_name: input_checkpoint})

        因此,对于以前的版本,如果您在实例化保护操作之前将图形写入 .pb 文件,则会出现问题。例如:

        tf.train.write_graph(sess.graph_def, "./logs", "test2.pb", False)
        saver = tf.train.Saver()
        saver.save(sess, "./logs/hello_ck.ckpt", meta_graph_suffix='meta', write_meta_graph=True)
        

        这是因为图形没有任何用于恢复模型的保存/恢复操作。要解决它,请在保存 .ckpt 文件后写入图形

        saver = tf.train.Saver()
        saver.save(sess, "./logs/hello_ck.ckpt", meta_graph_suffix='meta', write_meta_graph=True)
        tf.train.write_graph(sess.graph_def, "./logs", "test2.pb", False)
        

        @mrry,如果我解释错了,请指导。我最近才开始研究 tensorflow 代码。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-01-21
          • 2018-05-03
          • 1970-01-01
          • 2019-03-18
          • 2018-12-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多