Tensor
Python
TensorFlow
Machine Learning
Data Analysis

How to get the value of a tensor? Python

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

To get the value of a tensor in Python, the method depends on the framework. In TensorFlow 2.x (eager mode), call tensor.numpy() to get a NumPy array. In PyTorch, use tensor.item() for a single scalar or tensor.detach().cpu().numpy() for arrays. In TensorFlow 1.x (graph mode), you must run session.run(tensor) or tensor.eval() to evaluate the tensor. The key distinction is eager vs graph execution — eager mode computes values immediately, while graph mode requires explicit evaluation.

TensorFlow 2.x (Eager Mode — Default)

python
1import tensorflow as tf
2
3# Tensors have values immediately in eager mode
4tensor = tf.constant([[1, 2, 3], [4, 5, 6]])
5
6# Method 1: .numpy() — converts to NumPy array
7value = tensor.numpy()
8print(value)
9# [[1 2 3]
10#  [4 5 6]]
11print(type(value))  # <class 'numpy.ndarray'>
12
13# Method 2: Direct Python conversion for scalars
14scalar = tf.constant(42)
15print(int(scalar))      # 42
16print(float(scalar))    # 42.0
17
18# Method 3: tf.make_ndarray for TensorProto
19proto = tf.make_tensor_proto(tensor)
20array = tf.make_ndarray(proto)
21
22# Confirm eager mode is active
23print(tf.executing_eagerly())  # True

TensorFlow 1.x (Graph Mode)

python
1import tensorflow.compat.v1 as tf
2tf.disable_eager_execution()
3
4# In graph mode, tensors are symbolic — no value yet
5a = tf.constant([[1, 2], [3, 4]])
6b = tf.constant([[5, 6], [7, 8]])
7c = tf.matmul(a, b)
8
9print(c)  # Tensor("MatMul:0", shape=(2, 2), dtype=int32) — no values!
10
11# Must run in a session to get actual values
12with tf.Session() as sess:
13    # Method 1: session.run()
14    result = sess.run(c)
15    print(result)
16    # [[19 22]
17    #  [43 50]]
18
19    # Method 2: tensor.eval()
20    result = c.eval()
21    print(result)
22
23    # Multiple tensors at once
24    a_val, b_val, c_val = sess.run([a, b, c])
25
26    # With feed_dict for placeholders
27    x = tf.placeholder(tf.float32, shape=[None, 2])
28    y = x * 2
29    result = sess.run(y, feed_dict={x: [[1, 2], [3, 4]]})
30    print(result)  # [[2. 4.] [6. 8.]]

PyTorch

python
1import torch
2
3# PyTorch tensors are eager by default
4tensor = torch.tensor([[1, 2, 3], [4, 5, 6]])
5
6# Method 1: .numpy() — for CPU tensors without gradients
7array = tensor.numpy()
8print(array)
9
10# Method 2: .item() — for single scalar values
11scalar = torch.tensor(42)
12print(scalar.item())  # 42
13
14# Method 3: .tolist() — convert to Python list
15print(tensor.tolist())  # [[1, 2, 3], [4, 5, 6]]
16
17# For GPU tensors
18if torch.cuda.is_available():
19    gpu_tensor = tensor.cuda()
20    # Must move to CPU first
21    array = gpu_tensor.cpu().numpy()
22
23# For tensors with gradients
24x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
25y = x * 2
26# x.numpy()  # RuntimeError: Can't call numpy() on Tensor that requires grad
27array = x.detach().numpy()  # Detach from computation graph first
28print(array)  # [1. 2. 3.]
29
30# Full pattern for any PyTorch tensor
31array = tensor.detach().cpu().numpy()

NumPy Interoperability

python
1import numpy as np
2
3# NumPy to TensorFlow
4np_array = np.array([1, 2, 3])
5tf_tensor = tf.constant(np_array)
6print(tf_tensor.numpy())  # [1 2 3]
7
8# NumPy to PyTorch
9torch_tensor = torch.from_numpy(np_array)
10print(torch_tensor.numpy())  # [1 2 3]
11
12# Shared memory (PyTorch)
13np_array = np.array([1, 2, 3])
14torch_tensor = torch.from_numpy(np_array)
15np_array[0] = 99
16print(torch_tensor)  # tensor([99,  2,  3]) — shared memory!
17
18# TensorFlow creates a copy (no shared memory)
19tf_tensor = tf.constant(np_array)
20np_array[0] = 0
21print(tf_tensor.numpy())  # [99  2  3] — original value preserved

Getting Values During Training

python
1# TensorFlow 2 — eager mode in custom training
2model = tf.keras.Sequential([tf.keras.layers.Dense(10)])
3optimizer = tf.keras.optimizers.Adam()
4
5for x_batch, y_batch in dataset:
6    with tf.GradientTape() as tape:
7        predictions = model(x_batch)
8        loss = loss_fn(y_batch, predictions)
9
10    # Inspect values during training
11    print(f"Loss: {loss.numpy():.4f}")
12    print(f"Predictions mean: {tf.reduce_mean(predictions).numpy():.4f}")
13
14    gradients = tape.gradient(loss, model.trainable_variables)
15    optimizer.apply_gradients(zip(gradients, model.trainable_variables))
16
17# PyTorch — values available anytime
18for x_batch, y_batch in dataloader:
19    predictions = model(x_batch)
20    loss = criterion(predictions, y_batch)
21
22    print(f"Loss: {loss.item():.4f}")
23    print(f"Predictions: {predictions.detach().cpu().numpy()}")
24
25    loss.backward()
26    optimizer.step()

Tensor Properties

python
1# TensorFlow
2t = tf.constant([[1.0, 2.0], [3.0, 4.0]])
3print(t.shape)     # (2, 2)
4print(t.dtype)     # <dtype: 'float32'>
5print(t.device)    # /job:localhost/replica:0/task:0/device:CPU:0
6print(t.numpy())   # [[1. 2.] [3. 4.]]
7
8# PyTorch
9t = torch.tensor([[1.0, 2.0], [3.0, 4.0]])
10print(t.shape)     # torch.Size([2, 2])
11print(t.dtype)     # torch.float32
12print(t.device)    # cpu
13print(t.numpy())   # [[1. 2.] [3. 4.]]
14print(t.item())    # ValueError — only works for single-element tensors

Common Pitfalls

  • Calling .numpy() on a GPU tensor in PyTorch: tensor.numpy() only works on CPU tensors. For GPU tensors, call .cpu() first: tensor.cpu().numpy(). Forgetting this raises TypeError: can't convert cuda:0 device type tensor to numpy.
  • Calling .numpy() on a tensor with requires_grad=True: PyTorch tensors that track gradients cannot be converted directly. Call .detach() first to remove the tensor from the computation graph: tensor.detach().numpy(). The safe universal pattern is tensor.detach().cpu().numpy().
  • Using .numpy() in TensorFlow graph mode (TF1): In TensorFlow 1.x or when eager mode is disabled, tensors are symbolic and have no values. .numpy() raises AttributeError. Use session.run(tensor) or tensor.eval() within a session context instead.
  • Shared memory between PyTorch tensors and NumPy arrays: torch.from_numpy(array) creates a tensor that shares memory with the original array. Modifying one changes the other. Use .clone() or .copy() if you need independent copies.
  • Using print(tensor) expecting the full value: For large tensors, both TensorFlow and PyTorch truncate the printed output (showing ... for middle elements). Use tensor.numpy() with np.set_printoptions(threshold=np.inf) to see all values, or index specific elements with tensor[0:5].numpy().

Summary

  • TensorFlow 2 (eager): tensor.numpy() — works immediately, returns NumPy array
  • TensorFlow 1 (graph): session.run(tensor) or tensor.eval() — requires a session
  • PyTorch: tensor.detach().cpu().numpy() — handles gradients and GPU tensors safely
  • Use .item() for single scalar values in PyTorch, int(tensor) or float(tensor) in TensorFlow
  • Be aware of shared memory between PyTorch tensors and NumPy arrays created with from_numpy

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.