TensorFlow
print weights
machine learning
Python
deep learning

How to print weights in Tensorflow?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Inspecting model weights in TensorFlow helps verify that layers are connected as expected and training is actually updating parameters. Whether you use Keras APIs or custom training loops, the core approach is to access layer variables and print selected values or summaries. This is useful for debugging initialization, drift, and convergence issues.

In TensorFlow 2, most users work with Keras models. Each trainable layer exposes weights through get_weights and variable objects.

python
1import tensorflow as tf
2
3model = tf.keras.Sequential([
4    tf.keras.layers.Dense(8, activation="relu", input_shape=(4,)),
5    tf.keras.layers.Dense(3)
6])
7
8# Build weights by calling once.
9_ = model(tf.random.normal((1, 4)))
10
11for layer in model.layers:
12    print("Layer:", layer.name)
13    for w in layer.weights:
14        print(" ", w.name, w.shape)

To print actual numeric arrays:

python
1for layer in model.layers:
2    arrays = layer.get_weights()
3    for i, arr in enumerate(arrays):
4        print(layer.name, "array", i, "shape", arr.shape)
5        print(arr)

get_weights returns NumPy arrays, which are easy to inspect or save.

Some layers contain both trainable and non-trainable variables. Batch normalization is a common example.

python
1for var in model.trainable_variables:
2    print("trainable:", var.name, var.shape)
3
4for var in model.non_trainable_variables:
5    print("non_trainable:", var.name, var.shape)

This distinction matters when you freeze layers during transfer learning.

Inspect Weights During Training

Logging weights every step is expensive, but periodic snapshots can reveal training behavior.

python
1import numpy as np
2import tensorflow as tf
3
4x = np.random.randn(64, 4).astype("float32")
5y = np.random.randn(64, 3).astype("float32")
6
7model.compile(optimizer="adam", loss="mse")
8
9class WeightPrinter(tf.keras.callbacks.Callback):
10    def on_epoch_end(self, epoch, logs=None):
11        kernel = self.model.layers[0].kernel.numpy()
12        print(f"epoch {epoch+1}: first-layer kernel mean={kernel.mean():.6f}")
13
14model.fit(x, y, epochs=3, verbose=0, callbacks=[WeightPrinter()])

Printing summary statistics such as mean, std, min, and max is usually more practical than printing full matrices.

With tf.GradientTape, you access the same variables directly.

python
1optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)
2loss_fn = tf.keras.losses.MeanSquaredError()
3
4for step in range(5):
5    with tf.GradientTape() as tape:
6        pred = model(x, training=True)
7        loss = loss_fn(y, pred)
8
9    grads = tape.gradient(loss, model.trainable_variables)
10    optimizer.apply_gradients(zip(grads, model.trainable_variables))
11
12    if step % 2 == 0:
13        print("step", step, "loss", float(loss))
14        print("first var sample", model.trainable_variables[0].numpy().ravel()[:5])

This is useful when debugging gradient flow in advanced training logic.

Save Weight Snapshots for Offline Analysis

Instead of printing everything to console, save arrays to files for comparison across epochs.

python
1import numpy as np
2
3weights = model.get_weights()
4for idx, arr in enumerate(weights):
5    np.save(f"weight_{idx}.npy", arr)

Later you can load and compare:

python
w0 = np.load("weight_0.npy")
print(w0.shape, w0.mean(), w0.std())

This avoids noisy logs and helps version model state cleanly.

Inspect Weights by Layer Name Quickly

For larger models, filtering by layer name is easier than printing all variables.

python
1target = model.get_layer(index=0)   # or model.get_layer(\"dense\") if named
2print(\"layer\", target.name)
3print(\"kernel shape\", target.kernel.shape)
4print(\"bias shape\", target.bias.shape)
5print(\"kernel first row\", target.kernel.numpy()[0])

You can also compare snapshots before and after one optimization step to confirm updates are happening.

For convolutional models, inspecting per-channel statistics can reveal dead filters early in training. A simple min and max check per kernel often surfaces initialization or learning-rate issues before accuracy metrics diverge.

Common Pitfalls

A common mistake is trying to read layer weights before the model is built. Call the model once with sample input or specify input shape so variables exist.

Another issue is printing huge matrices every iteration, which slows training and makes logs unusable. Print sampled values or summary statistics instead.

Developers also assume layer.weights are always trainable. Use trainable_variables and non_trainable_variables to avoid confusion, especially with normalization layers.

Summary

  • Access TensorFlow weights through layer variables or get_weights.
  • Build the model before inspecting weights.
  • Distinguish trainable and non-trainable variables.
  • Log concise weight summaries during training for practical debugging.
  • Save snapshot files when detailed offline analysis is needed.

Course illustration
Course illustration

All Rights Reserved.