How to get Graph or GraphDef from a given Model?
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.
Introduction
When working with TensorFlow, you often need to inspect or export the computational graph underlying your model. Whether you are debugging layer connections, optimizing for deployment, or converting between formats, extracting the Graph or GraphDef is a fundamental skill. This article walks you through the different approaches for TensorFlow 1.x, TensorFlow 2.x, and Keras models, so you can choose the right method for your situation.
Understanding Graph vs GraphDef
Before diving into extraction methods, it helps to understand why these two objects exist. A tf.Graph is TensorFlow's in-memory representation of a computational graph. It holds operations, tensors, and their relationships. A GraphDef is the serialized Protocol Buffer version of that graph, which you can save to disk, transfer between systems, or load into a different runtime. Think of Graph as the live object and GraphDef as its portable snapshot.
Extracting the Graph in TensorFlow 1.x
In TF1, every operation you create lands in a default graph, and sessions hold a reference to it. This makes extraction straightforward.
The as_graph_def() method returns a GraphDef protobuf that captures every operation and tensor in the graph at that moment. This is the object you serialize when saving .pb files.
Extracting the Graph in TensorFlow 2.x with tf.function
TensorFlow 2.x defaults to eager execution, which means there is no global graph sitting around to grab. To get a graph, you need to trace a function using tf.function, which converts your Python code into a reusable computational graph.
The key insight is that get_concrete_function forces TensorFlow to trace the function with a specific input signature, producing a ConcreteFunction whose .graph attribute gives you the traced graph.
Extracting the Graph from a Keras Model
For Keras models, wrap the model's call method with tf.function to generate a traceable graph.
Setting training=False ensures you capture the inference graph, which excludes dropout and batch normalization training behavior.
Freezing and Saving a GraphDef as .pb
A frozen graph bundles the model's weights directly into the GraphDef, producing a single self-contained file. This is essential for deployment scenarios where you want one portable artifact.
Using tf.compat.v1 for Legacy Code
If you are maintaining a codebase that mixes TF1 and TF2 patterns, tf.compat.v1 provides the bridge. Disabling eager execution restores the TF1 session-based workflow.
This approach is useful when you need to load older saved models or interface with tools that expect a TF1-style GraphDef.
Common Pitfalls
- Calling
as_graph_def()in eager mode withouttf.functionleads to an empty or nonexistent graph because there is no graph to extract in pure eager execution. - Forgetting to call
get_concrete_functionwith an input signature means TensorFlow cannot trace the function and will raise an error about unknown shapes. - Omitting
training=Falsein Keras model wrapping captures training-only operations like dropout, producing an inference graph that behaves differently than expected. - Confusing frozen graphs with SavedModel format results in lost flexibility, since a frozen
.pbfile converts variables to constants and cannot be fine-tuned afterward. - Mixing
tf.compat.v1.disable_eager_execution()with eager code is a global setting that affects all subsequent TensorFlow operations, causing subtle bugs in other parts of your script.
Summary
- Use
sess.graph.as_graph_def()in TensorFlow 1.x to extract graphs from sessions. - In TensorFlow 2.x, wrap your logic in
tf.functionand callget_concrete_function()to produce a traceable graph. - For Keras models, wrap
model(x, training=False)in atf.functionwith an explicitinput_signature. - Freeze graphs with
convert_variables_to_constants_v2to bundle weights into a single.pbfile for deployment. - Use
tf.compat.v1when working with legacy TF1 codebases, but avoid mixing it with eager execution in the same script. - Always provide explicit input shapes when tracing, since TensorFlow needs concrete dimensions to build the graph.
Related reading
- How to get labels ids in Keras when training on multiple classes?
- How to get output of hidden layer given an input, weights and biases of the hidden layer in keras?
- How to get PI in tensorflow?
- How to get reproducible result when running Keras with Tensorflow backend
- How to get inertia value for each k-means cluster using scikit-learn?
- How to get mini-batches in pytorch in a clean and efficient way?
- How to Get Reproducible Results Keras, Tensorflow
- How to get rid of tensorflow verbose messages with Keras
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.