TensorFlow freeze_graph.py: The name 'save/Con

2019-04-04 19:35发布

问题:

I am currently trying to export a trained TensorFlow model as a ProtoBuf file to use it with the TensorFlow C++ API on Android. Therefore, I'm using the freeze_graph.py script.

I exported my model using tf.train.write_graph:

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

and I'm using a checkpoint saved with tf.train.Saver.

I invoke freeze_graph.py as described at the top of the script. After compiling, I run

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

This gives me the following error message:

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.

As the error states I do not have a tensor save/Const:0 in my exported model. However, the code of freeze_graph.py says that one can specify this tensor name by the flag filename_tensor_name. Unfortunately I cannot find any information on what this tensor should be and how to set it correctly for my model.

Can somebody tell my either how to produce a save/Const:0 tensor in my exported ProtoBuf model or how to set the flag filename_tensor_name correctly?

回答1:

The --filename_tensor_name flag is used to specify the name of a placeholder tensor created when you construct a tf.train.Saver for your model.*

In your original program, you can print out the value of saver.saver_def.filename_tensor_name to get the value that you should pass for this flag. You may also want to print the value of saver.saver_def.restore_op_name to get a value for the --restore_op_name flag (since I suspect the default won't be correct for your graph).

Alternatively, the tf.train.SaverDef protocol buffer includes all of the information you need to reconstruct the relevant information for these flags. If you prefer, you can write saver.saver_def to a file, and pass the name of that file as the --input_saver flag to freeze_graph.py.


 * The default name scope for a tf.train.Saver is "save/" and the placeholder is actually a tf.constant() whose name defaults to "Const:0", which explains why the flag defaults to "save/Const:0".



回答2:

I noticed that error happened to me when I had code arranged like this:

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)

It worked after I changed code layout like this:

# 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)

I'm not really sure why is that. @mrry could you explain it a bit more?



回答3:

It should not be problematic in latest freeze_graph.py as I could see these removed:

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

In earlier version, it was using restore_op to restore the model

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

So, for previous version, if you are writing the graph in .pb file before instantiating saver op, it will problematic. eg.:

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)

This is because graph won't have any save/restore op for restoration of model. To resolve it, write graph after saving the .ckpt file

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, please guide if I interpreted something wrong. I only recently started diving into tensorflow code.