Steve Severance
Steve Severance

Reputation: 6656

How to properly freeze a tensorflow graph containing a LookupTable

I am working with a model that uses multiple lookup tables to transform the model input from text to feature ids. I am able to train the model fine. I am able to load it via the javacpp bindings. I am using a default Saver object via the tensor flow supervisor on a periodic basis.

When I try to run the model I get the following error:

Table not initialized.
 [[Node: hash_table_Lookup_3 = LookupTableFind[Tin=DT_STRING, Tout=DT_INT64, 
_class=["loc:@string_to_index_2/hash_table"], _output_shapes=[[-1]],
_device="/job:localhost/replica:0/task:0/cpu:0"]
(string_to_index_2/hash_table, ParseExample/ParseExample:5, string_to_index_2/hash_table/Const)]]

I prepare the model by using the freeze_graph.py script as follows:

bazel-bin/tensorflow/python/tools/freeze_graph --input_graph=/tmp/tf/graph.pbtxt 
--input_checkpoint=/tmp/tf/model.ckpt-0 --output_graph=/tmp/ticker_classifier.pb 
--output_node_names=sigmoid --initializer_nodes=init_all_tables

As far as I can tell specifying the initializer_nodes has no effect on the resulting file. Am I running into something that is not currently supported? If not than is there something else I need to do to prepare the graph to be frozen?

Upvotes: 2

Views: 1152

Answers (1)

Yan
Yan

Reputation: 386

I had the same problem when using C++ to invoke TF API to run the inference. It seems the reason is I train a model using tf.feature_column.categorical_column_with_hash_bucket, which needs to be initialized like this:

        table_init_op = tf.tables_initializer(name="init_all_tables")
        sess.run(table_init_op)

So when you want to freeze the model, you must append the name of table_init_op to the argument "--output_node_names":

freeze_graph --input_graph=/tmp/tf/graph.pbtxt 
             --input_checkpoint=/tmp/tf/model.ckpt-0
             -- output_graph=/tmp/ticker_classifier.pb 
             --output_node_names=sigmoid,init_all_tables
             --initializer_nodes=init_all_tables

When you load and init model in C++, you should first invoke TF C++ API like this:

std::vector<Tensor> dummy_outputs;
Status st = session->Run({}, {}, {"init_all_tables"}, dummy_outputs);

Now you have initialized all tables and can do other things such as inference. This issue may give you a help.

Upvotes: 2

Related Questions