In TensorFlow 1, a model’s graph and its weights were saved apart: the graph as a GraphDef, and the values of its variables in a checkpoint. Freezing joins them into one file. Frozen graphs were the usual way to hand a trained TensorFlow 1 model to another program.
What freezing does
- Start from the graph and a checkpoint of its trained variables.
- Keep only the nodes needed to compute the chosen outputs.
- Replace each variable node with a
Constnode of the same name, whosevalueattribute is a TensorProto holding the variable’s trained values, and whosedtypeattribute is its type. - Write the result as one GraphDef.
The tools that do this are TensorFlow 1’s freeze_graph and the function
convert_variables_to_constants, available in TensorFlow 2 as
tf.compat.v1.graph_util.convert_variables_to_constants.
The weights as Const nodes
In the file, each weight is a NodeDef
like any other: a name, the op Const, and two attributes. The values are
usually raw bytes in tensor_content;
a tensor whose values are all the same can instead hold one value in a typed field,
which TensorFlow repeats to fill the
shape.
| Part of the node | Holds |
|---|---|
name | The variable’s name, so that nodes that read it still find it. |
op | Const. |
attr dtype | The data type, such as DT_FLOAT. |
attr value | The tensor: dtype, shape and values. |
The explorer counts the Const nodes of a GraphDef and notes that in a
frozen graph they are the weights. Nothing in the file marks it as frozen: a graph
with no variable nodes and many constants is one by its content.
Where frozen graphs are used
A frozen graph needs no Python code and no checkpoint, so tools that convert or run
TensorFlow models outside TensorFlow have commonly taken them as input. TensorFlow 2
replaced them with the SavedModel, whose
saved_model.pb keeps the graph and leaves the weights in a
variables folder.