TensorFlow 2.0 How to get trainable variables from tf.keras.layers layers, like Conv2D or Dense
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In TensorFlow 2, Keras layers expose their trainable parameters directly once the layer has been built. The main thing to understand is that a Dense or Conv2D layer does not create its weights until it has seen an input shape, so asking for trainable variables too early often returns an empty list.
What Counts as a Trainable Variable
For common Keras layers, the trainable variables are usually the kernel weights and, if enabled, the bias.
For example:
- '
Denseusually haskernelandbias' - '
Conv2Dusually has convolutionkerneland optionalbias' - custom layers may register any
tf.Variablemarked as trainable
TensorFlow collects these variables under properties such as:
- '
layer.trainable_variables' - '
layer.trainable_weights' - '
model.trainable_variables'
In most modern code, trainable_variables is the clearest property to use.
The Layer Must Be Built First
A layer that has not been built yet does not know its input dimensionality, so it cannot allocate weights.
After the call layer(x), the layer is built and the variables exist.
This is the most common source of confusion. The API is correct; the layer simply has not created its variables yet.
Accessing Variables on Dense
For Dense, the kernel shape is usually (input_dim, units) and the bias shape is (units,).
Accessing Variables on Conv2D
For Conv2D, the kernel shape is typically (kernel_height, kernel_width, in_channels, filters).
From Layers to Models
If you want all trainable variables in a whole network, ask the model instead of each layer individually.
This is especially useful in custom training loops, where you pass model.trainable_variables to a gradient tape and optimizer.
trainable = False Changes the List
If a layer is frozen, its variables still exist, but they are no longer returned as trainable variables for optimization.
This matters during transfer learning. layer.variables still includes the weights, but layer.trainable_variables becomes empty for that layer.
Why This Matters in Custom Training
A manual training step usually looks like this:
If the layer or model was not built, or if you accidentally froze it, that variable list may be empty and nothing will update.
Common Pitfalls
The most common mistake is inspecting trainable_variables before the layer has been built. Call the layer once or define the input shape first.
Another mistake is confusing variables with trainable_variables. The first includes all variables, while the second includes only those that should be optimized.
A third issue is freezing a layer with trainable = False and then expecting its variables to appear in the optimizer step.
Finally, when debugging nested models, remember that model.trainable_variables is usually easier to reason about than crawling every sublayer manually.
Summary
- Use
layer.trainable_variablesto get a layer's trainable parameters. - Keras layers do not create weights until they are built.
- Call the layer once or provide input shape before inspecting variables.
- '
DenseandConv2Dusually exposekerneland optionalbias.' - Use
model.trainable_variablesfor whole-model training logic. - If
trainable = False, the weights still exist but drop out of the trainable list.

