iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Tensors

TensorFlow tensors: rank, shape, dtype, device, eager vs graph. The mental model that underlies everything from a single layer to a training loop.

TensorFlow — tensors

EXAMPLE
import tensorflow as tf

# ===== Creation =====
a = tf.constant(3.0)                                  # scalar (rank 0)
v = tf.constant([1.0, 2.0, 3.0])                       # vector (rank 1)
m = tf.constant([[1.0, 2.0], [3.0, 4.0]])              # matrix (rank 2)
z = tf.zeros([2, 3, 4])                                # rank 3 tensor
o = tf.ones([3, 3])

# From numpy:
import numpy as np
n = tf.convert_to_tensor(np.arange(12, dtype=np.float32).reshape(3, 4))

# ===== The five attributes you reach for =====
print(a.shape, a.dtype, a.device, a.numpy(), tf.rank(a).numpy())

# ===== dtype matters (mixed precision = real perf) =====
x = tf.constant([1.0, 2.0], dtype=tf.float32)
y = tf.constant([1, 2], dtype=tf.int32)
# x + y -> error: dtypes must match; cast explicitly.
y_f = tf.cast(y, tf.float32)
print(x + y_f)

# ===== Variables (trainable state) =====
w = tf.Variable(tf.random.normal([4, 3]))
b = tf.Variable(tf.zeros([3]))

# Updates are explicit:
w.assign(w * 0.99)
b.assign_add(tf.ones([3]) * 0.01)

# ===== Indexing and slicing =====
m[0, 1]
m[:, 1]                  # column 1
m[1, :]                  # row 1
m[..., 1]                # ellipsis: keep all leading axes

# Boolean mask:
mask = m > 2.0
tf.boolean_mask(m, mask)

# ===== Reshape =====
r = tf.reshape(z, [-1, 4])         # -1 = infer
t = tf.transpose(m)                # swap axes (default: reverse)
tf.expand_dims(v, axis=0).shape    # (1, 3)
tf.squeeze(tf.zeros([1, 4, 1])).shape  # (4,)

# ===== Math (broadcasting like NumPy) =====
m2 = m + 1.0
m3 = m * m2
m4 = tf.matmul(m, tf.transpose(m))
print(tf.reduce_sum(m4, axis=0))

# ===== GPU placement =====
print('GPU available:', tf.config.list_physical_devices('GPU'))
with tf.device('/CPU:0'):
    x_cpu = tf.random.normal([1000, 1000])

# ===== Eager (default) vs Graph (tf.function) =====
@tf.function
def step(x, w, b):
    return tf.matmul(x, w) + b

# tf.function traces Python code into a graph; faster on hot paths.

# ===== Automatic differentiation =====
x = tf.Variable(3.0)
with tf.GradientTape() as tape:
    y = x ** 2 + 2 * x + 1
dy_dx = tape.gradient(y, x)
print(dy_dx.numpy())                # 8.0

# Multi-variable:
w = tf.Variable(tf.random.normal([3, 2]))
b = tf.Variable(tf.zeros([2]))
X = tf.random.normal([10, 3]); y = tf.random.normal([10, 2])
with tf.GradientTape() as tape:
    pred = X @ w + b
    loss = tf.reduce_mean((pred - y) ** 2)
grads = tape.gradient(loss, [w, b])

# ===== Patterns to internalise =====
# - Stay aware of rank/shape/dtype/device at all times
# - Use tf.cast over operator promotion (which TF refuses silently for safety)
# - tf.function on training step for graph mode + XLA wins
# - GradientTape for any custom gradient; Keras uses it under the hood
# - Variables for trainable state; tensors for everything else

# ===== Pitfalls =====
# - shape mismatch in matmul -> read the error backwards: (M, K) @ (K, N)
# - Mixing tf.constant and python int in tf.function -> retraces every call
# - Forgetting tf.cast -> 'cannot compute Op: int + float'
# - Updating Variable with = instead of assign() -> rebinds the Python name, no graph effect
# - Capturing a Variable inside tf.function from outer scope -> ok ONCE; recreating it breaks tracing

Why it matters

Tensors are NumPy with a GPU, a tape, and a graph. Rank/shape/dtype/device + Variables + GradientTape are 80% of TF. Once these are reflex, the rest of TensorFlow is layers + optimizers + datasets built on top.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
import tensorflow as tf
a = tf.constant([[1, 2], [3, 4]])
b = tf.ones((2, 2))
print(a + b)
print(tf.matmul(a, b))
Try it Yourself »

Discussion

Loading…