Why is convert_variables_to_constants() deprecated in TF2?

Viewed 1065

As the title says, why is convert_variables_to_constants() deprecated in tensorflow 2? What's the easy replacement to get a saveable model to load into a downstream stand-alone application for inference (in my case, using the C API).

1 Answers

In TF 2.x there is no tf.Session(), which is a necessary component to build frozen models in TF 1.x, anymore in TF 2.0.

According to TensorFlow 2.0.0 release description "Removed the freeze_graph command-line tool; SavedModel should be used in place of frozen graphs." So, you would be expected to use SavedModel only.

However, if you still need frozen graphs you

# Save model to SavedModel format
tf.saved_model.save(model, "./models/simple_model")

# Convert Keras model to ConcreteFunction
full_model = tf.function(lambda x: model(x))
full_model = full_model.get_concrete_function(
    x=tf.TensorSpec(model.inputs[0].shape, model.inputs[0].dtype))

# Get frozen ConcreteFunction
frozen_func = convert_variables_to_constants_v2(full_model)
frozen_func.graph.as_graph_def()

layers = [op.name for op in frozen_func.graph.get_operations()]

And then save it as a frozen graph.

Note: You would now be expected to load this frozen graph with TF 1.x functions,

tf.io.write_graph(graph_or_graph_def=frozen_func.graph,
                  logdir="./frozen_models",
                  name="simple_frozen_graph.pb",
                  as_text=False)

Then to load this model (TF 1.x code) you would do-

with tf.io.gfile.GFile("./frozen_models/simple_frozen_graph.pb", "rb") as f:
    graph_def = tf.compat.v1.GraphDef()
    loaded = graph_def.ParseFromString(f.read())

The latency reduced by freeze_graph may be quite important for an application and full-precision weights being stored in SavedModel could be a problem. But there are simple ways to get past this too, which is outside the scope of this question.

Related