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?
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"
.
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?
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.