TensorFlow
TensorFlow 2.0
print tensor values
machine learning
deep learning

TF 2.0 print tensor values

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

TensorFlow 2.0 uses eager execution by default, which means tensors evaluate immediately and their values can be printed with standard Python print(). In TF 1.x, tensors were symbolic graph nodes and printing them showed metadata (shape, dtype) instead of values. TF 2.0 eliminates this friction — print(tensor) shows the actual values. For tensors inside @tf.function (graph mode), use tf.print() instead of Python print(). This article covers all printing approaches for debugging TensorFlow code.

Eager Execution (Default in TF 2.0)

python
1import tensorflow as tf
2
3# Tensors evaluate immediately — print shows values
4a = tf.constant([1, 2, 3])
5print(a)
6# tf.Tensor([1 2 3], shape=(3,), dtype=int32)
7
8# Access the raw NumPy value
9print(a.numpy())
10# [1 2 3]
11
12# Arithmetic results are also immediate
13b = tf.constant([4, 5, 6])
14c = a + b
15print(c)
16# tf.Tensor([5 7 9], shape=(3,), dtype=int32)
17print(c.numpy())
18# [5 7 9]

print(tensor) shows the tensor wrapper with shape and dtype. .numpy() extracts the raw NumPy array for cleaner output.

Printing Inside @tf.function

python
1import tensorflow as tf
2
3@tf.function
4def compute(x):
5    y = x * 2
6
7    # Python print() runs only during tracing, NOT during execution
8    print("This prints once during tracing:", y)  # Shows symbolic tensor
9
10    # tf.print() runs every time the function is called
11    tf.print("Value of y:", y)
12
13    return y
14
15result = compute(tf.constant(5))
16# Tracing output: This prints once during tracing: Tensor("mul:0", shape=(), dtype=int32)
17# Runtime output: Value of y: 10

Inside @tf.function, Python print() only executes during the tracing phase (first call). Use tf.print() for output on every call.

tf.print for Detailed Output

python
1import tensorflow as tf
2
3tensor = tf.random.normal([3, 4])
4
5# Basic tf.print
6tf.print(tensor)
7
8# With formatting
9tf.print("Shape:", tf.shape(tensor))
10tf.print("Mean:", tf.reduce_mean(tensor))
11tf.print("Max:", tf.reduce_max(tensor))
12
13# Control output format
14tf.print(tensor, output_stream='stderr')  # Print to stderr
15tf.print(tensor, summarize=-1)  # Print all elements (no truncation)
16
17# Multiple values
18x = tf.constant([1, 2, 3])
19y = tf.constant([4, 5, 6])
20tf.print("x:", x, "y:", y, "sum:", x + y)

tf.print() is a TensorFlow operation that executes within the graph. It supports summarize to control how many elements are shown for large tensors.

Printing Large Tensors

python
1import tensorflow as tf
2import numpy as np
3
4large_tensor = tf.random.normal([100, 100])
5
6# Default print truncates large tensors
7print(large_tensor)  # Shows first/last few values with ...
8
9# Print all values using NumPy
10np.set_printoptions(threshold=np.inf)
11print(large_tensor.numpy())
12
13# Or use tf.print with summarize=-1
14tf.print(large_tensor, summarize=-1)
15
16# Print specific slices
17print("First row:", large_tensor[0].numpy())
18print("Column 5:", large_tensor[:, 5].numpy())
19print("Top-left 3x3:", large_tensor[:3, :3].numpy())

For large tensors, print slices or summary statistics instead of the full array.

Debugging During Training

python
1import tensorflow as tf
2
3model = tf.keras.Sequential([
4    tf.keras.layers.Dense(64, activation='relu'),
5    tf.keras.layers.Dense(10)
6])
7
8# Custom training loop with printing
9@tf.function
10def train_step(x, y):
11    with tf.GradientTape() as tape:
12        predictions = model(x, training=True)
13        loss = tf.keras.losses.sparse_categorical_crossentropy(y, predictions, from_logits=True)
14        loss = tf.reduce_mean(loss)
15
16    # Print loss every step
17    tf.print("Loss:", loss)
18    tf.print("Predictions range:", tf.reduce_min(predictions), "to", tf.reduce_max(predictions))
19
20    gradients = tape.gradient(loss, model.trainable_variables)
21    optimizer.apply_gradients(zip(gradients, model.trainable_variables))
22    return loss
23
24# Or use a Keras callback
25class PrintCallback(tf.keras.callbacks.Callback):
26    def on_epoch_end(self, epoch, logs=None):
27        print(f"Epoch {epoch}: loss={logs['loss']:.4f}")
28
29        # Print layer weights
30        for layer in self.model.layers:
31            weights = layer.get_weights()
32            if weights:
33                print(f"  {layer.name}: mean={np.mean(weights[0]):.4f}")

Comparing TF 1.x vs TF 2.0

python
1# TensorFlow 1.x — required Session to see values
2# import tensorflow as tf
3# a = tf.constant([1, 2, 3])
4# print(a)  # Tensor("Const:0", shape=(3,), dtype=int32) — NO VALUES
5# with tf.Session() as sess:
6#     print(sess.run(a))  # [1 2 3] — only way to see values
7
8# TensorFlow 2.0 — values are immediate
9import tensorflow as tf
10a = tf.constant([1, 2, 3])
11print(a)          # tf.Tensor([1 2 3], shape=(3,), dtype=int32)
12print(a.numpy())  # [1 2 3]

Tensor Properties

python
1import tensorflow as tf
2
3t = tf.constant([[1.0, 2.0], [3.0, 4.0]])
4
5print(f"Shape: {t.shape}")        # (2, 2)
6print(f"Dtype: {t.dtype}")        # <dtype: 'float32'>
7print(f"Device: {t.device}")      # /job:localhost/replica:0/task:0/device:CPU:0
8print(f"NumPy:\n{t.numpy()}")     # [[1. 2.] [3. 4.]]
9print(f"Rank: {tf.rank(t).numpy()}")  # 2
10print(f"Size: {tf.size(t).numpy()}")  # 4

Common Pitfalls

  • Using print() inside @tf.function: Python print() only runs during tracing (first call). On subsequent calls with the same input signature, it does not print. Use tf.print() for consistent output.
  • Calling .numpy() on GPU tensors in hot loops: .numpy() copies data from GPU to CPU, which is slow. Avoid calling it inside training loops. Use tf.print() instead, which prints from the device directly.
  • Large tensor output truncation: Both print() and tf.print() truncate large tensors by default. Use np.set_printoptions(threshold=np.inf) or tf.print(tensor, summarize=-1) to see all values.
  • Printing inside tf.data pipelines: print() inside .map() functions only executes during tracing. Use tf.print() or tf.py_function wrapper for side effects inside data pipelines.
  • Expecting TF 1.x behavior: In TF 1.x, print(tensor) showed only metadata. In TF 2.0, it shows actual values. Code migrated from TF 1.x may have unnecessary sess.run() calls that should be removed.

Summary

  • TF 2.0 uses eager execution — print(tensor) shows values directly
  • Use .numpy() to extract raw NumPy arrays from tensors
  • Use tf.print() inside @tf.function for output on every call
  • Use tf.print(tensor, summarize=-1) to print all elements of large tensors
  • Avoid .numpy() in training loops — it copies data from GPU to CPU
  • Print tensor properties with .shape, .dtype, and .device attributes

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track 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.

Practice ML system design

All Rights Reserved.