Tensor Flow 📂 Tensors · 3 of 6 40 min read

Creating Tensors in TensorFlow: tf.constant, tf.zeros and tf.random

Learn every common way to create a tensor: tf.constant from lists and NumPy, tf.zeros, tf.ones, tf.fill, tf.eye, tf.range and tf.linspace. Then create random tensors with normal, uniform and truncated normal, and make results repeatable with seeds and tf.random.Generator. Build tensors live in the Tensor Factory.

Section 01

The Story — Ice Cube Trays

Every Tensor Is a Tray
Think of an ice cube tray. It has a fixed number of rows and columns. Every slot holds the same kind of thing: water.

A tensor is the same. It has a fixed shape (rows, columns, and more). Every slot holds the same dtype, such as float32.

TensorFlow gives you many ways to make a tray. You can fill it with your own numbers (tf.constant), with zeros or ones (tf.zeros, tf.ones), or with random numbers (tf.random). Neural networks need all three.

In this lesson you will learn every common way to create a tensor. You will also see why random tensors matter so much, and how to make them repeatable with a seed.

✏️
tf.constant
your own data
Turn a Python list or NumPy array into a tensor.
0️⃣
tf.zeros / ones
filled tensors
Starting values for biases, masks and counters.
📏
tf.range / linspace
sequences
Evenly spaced numbers, like NumPy's arange.
🎲
tf.random
random values
Initial weights, dropout, noise and shuffling.

Section 02

tf.constant — Tensors From Your Data

tf.constant(value, dtype=None, shape=None) makes a tensor from a Python number, a list, a nested list, or a NumPy array. If you do not give a dtype, TensorFlow guesses it from the values.

import tensorflow as tf
import numpy as np

scalar = tf.constant(7)                        # rank 0
vector = tf.constant([1.5, 2.5, 3.5])          # rank 1
matrix = tf.constant([[1, 2, 3],
                      [4, 5, 6]])              # rank 2

print(scalar)
print(vector)
print(matrix)
OUTPUT
tf.Tensor(7, shape=(), dtype=int32) tf.Tensor([1.5 2.5 3.5], shape=(3,), dtype=float32) tf.Tensor( [[1 2 3] [4 5 6]], shape=(2, 3), dtype=int32)

How TensorFlow Picks the dtype

You passdtype you getNote
tf.constant(5)int32Python int
tf.constant(5.0)float32Python float
tf.constant(True)bool
tf.constant("hi")stringBytes, not maths
tf.constant(np.array([1.0]))float64NumPy default is float64!
from_numpy = tf.constant(np.array([1.0, 2.0]))
print("From NumPy:", from_numpy.dtype)

fixed = tf.constant(np.array([1.0, 2.0]), dtype=tf.float32)   # ask for float32
print("With dtype:", fixed.dtype)

filled = tf.constant(9, shape=(2, 3))           # repeat one value into a shape
print(filled)
OUTPUT
From NumPy: <dtype: 'float64'> With dtype: <dtype: 'float32'> tf.Tensor( [[9 9 9] [9 9 9]], shape=(2, 3), dtype=int32)
⚠️
The float64 Trap

Neural network weights are float32. NumPy arrays are float64 by default. Mixing them gives an error later. Pass dtype=tf.float32 when you convert NumPy data.

Tensors Must Be Rectangles

Every row must have the same length. A "jagged" list fails.

try:
    tf.constant([[1, 2, 3], [4, 5]])
except ValueError as e:
    print("ValueError:", str(e).split(".")[0])
OUTPUT
ValueError: Can't convert non-rectangular Python sequence to Tensor

For jagged data, TensorFlow has tf.ragged.constant. We cover it later in the course.

Tensors Are Immutable

You cannot change a value inside a tf.constant. You create a new tensor instead. For values that must change, such as model weights, use tf.Variable.

t = tf.constant([1, 2, 3])
try:
    t[0] = 100
except TypeError as e:
    print("TypeError:", e)

v = tf.Variable([1, 2, 3])
v[0].assign(100)                # Variables can change
print(v.numpy())
OUTPUT
TypeError: 'tensorflow.python.framework.ops.EagerTensor' object does not support item assignment [100 2 3]

Section 03

Filled Tensors — zeros, ones, fill, eye

print(tf.zeros([2, 3]))                         # all 0.0, float32
print(tf.ones([3], dtype=tf.int32))             # all 1
print(tf.fill([2, 2], 7.5))                     # any value you like
print(tf.eye(3))                                # identity matrix
OUTPUT
tf.Tensor( [[0. 0. 0.] [0. 0. 0.]], shape=(2, 3), dtype=float32) tf.Tensor([1 1 1], shape=(3,), dtype=int32) tf.Tensor( [[7.5 7.5] [7.5 7.5]], shape=(2, 2), dtype=float32) tf.Tensor( [[1. 0. 0.] [0. 1. 0.] [0. 0. 1.]], shape=(3, 3), dtype=float32)

Copy Another Tensor's Shape — zeros_like / ones_like

weights = tf.constant([[0.3, -1.2], [2.0, 0.7]])
grad_sum = tf.zeros_like(weights)     # same shape and dtype, all zeros
print(grad_sum)
OUTPUT
tf.Tensor( [[0. 0.] [0. 0.]], shape=(2, 2), dtype=float32)

Sequences — tf.range and tf.linspace

print(tf.range(5))                      # 0..4, like Python range
print(tf.range(2, 12, delta=3))         # start, limit (not included), step
print(tf.linspace(0.0, 1.0, num=5))     # 5 points, end included
OUTPUT
tf.Tensor([0 1 2 3 4], shape=(5,), dtype=int32) tf.Tensor([ 2 5 8 11], shape=(4,), dtype=int32) tf.Tensor([0. 0.25 0.5 0.75 1. ], shape=(5,), dtype=float32)
tf.range(start, limit, delta)
You choose the step
End value is not included
Keeps int dtype for int inputs
tf.linspace(start, stop, num)
You choose the count
End value is included
Needs float start and stop

Section 04

Try It — The Tensor Factory

🏭 Build Any Tensor Interactive

Pick a function and type the arguments. Press Create. Watch the tensor fill up, and see the Python code for it. Shape examples: 4, 2,3, 2,2,3.


Section 05

Random Tensors — tf.random

Why do we need random numbers? A new neural network starts with random weights. If all weights were zero, every neuron would learn the same thing. Randomness breaks this symmetry. Random numbers are also used for dropout, data augmentation and shuffling.

🔴
tf.random.normal
Bell curve. Most values near the mean. Spread set by stddev.
mean=0.0, stddev=1.0
▬
tf.random.uniform
Flat. Every value between minval and maxval is equally likely. maxval is not included.
minval=0, maxval=1
✂️
tf.random.truncated_normal
Bell curve, but values beyond 2 stddev are thrown away and drawn again. No extreme weights.
popular for weights
tf.random.set_seed(42)

print(tf.random.normal([2, 3], mean=0.0, stddev=1.0))
print(tf.random.uniform([2, 3], minval=0, maxval=10, dtype=tf.int32))
print(tf.random.truncated_normal([4], stddev=0.5))
OUTPUT
tf.Tensor( [[ 0.3274685 -0.8426258 0.3194337] [-1.4075519 -2.3880599 -1.0392479]], shape=(2, 3), dtype=float32) tf.Tensor( [[8 3 9] [4 2 3]], shape=(2, 3), dtype=int32) tf.Tensor([-0.27954867 -0.2673607 -0.78629655 0.4027528 ], shape=(4,), dtype=float32)

Other useful random ops:

tf.random.set_seed(7)
cards = tf.range(10)
print("shuffled :", tf.random.shuffle(cards).numpy())

logits = tf.math.log([[0.7, 0.2, 0.1]])                 # class probabilities
print("samples  :", tf.random.categorical(logits, num_samples=8).numpy())
OUTPUT
shuffled : [4 8 9 1 6 7 0 3 2 5] samples : [[0 0 1 0 0 1 2 1]]

Section 06

Seeds — Making Randomness Repeatable

The Shuffled Deck
A seed is like a secret code for shuffling a deck of cards. Use the same code, and the deck comes out in the same order every time. This lets you repeat an experiment, and lets a friend get the same results as you.

TensorFlow uses two seeds together: a global seed (tf.random.set_seed) and an optional op seed (the seed= argument).

tf.random.set_seed(1)
print("run 1:", tf.random.uniform([3]).numpy(), tf.random.uniform([3]).numpy())

tf.random.set_seed(1)            # reset -> the same sequence again
print("run 2:", tf.random.uniform([3]).numpy(), tf.random.uniform([3]).numpy())
OUTPUT
run 1: [0.16513085 0.9014813 0.6309742 ] [0.51010704 0.44353175 0.4085331 ] run 2: [0.16513085 0.9014813 0.6309742 ] [0.51010704 0.44353175 0.4085331 ]

Notice: within one run, the two calls give different numbers. But after resetting the seed, the whole sequence repeats.

The Modern Way — tf.random.Generator

A Generator keeps its own random state. It does not depend on the global seed. This is the clearest way to control randomness.

g = tf.random.Generator.from_seed(2024)
print(g.normal([3]).numpy())

g2 = tf.random.Generator.from_seed(2024)     # same seed -> same numbers
print(g2.normal([3]).numpy())
OUTPUT
[ 0.9029707 0.08384313 -0.43693087] [ 0.9029707 0.08384313 -0.43693087]

Stateless Random Ops

Stateless ops always return the same output for the same seed pair. They are handy inside tf.data pipelines.

a = tf.random.stateless_normal([3], seed=[1, 2])
b = tf.random.stateless_normal([3], seed=[1, 2])
print(a.numpy())
print("Same?", bool(tf.reduce_all(a == b)))
OUTPUT
[0.5441101 0.20738031 0.07356432] Same? True

Section 07

Try It — Random Distribution Explorer

🎲 See the Shape of Randomness Interactive

Draw many random numbers and see them as a histogram. Change the settings and press Sample. Use the same seed twice to get the same picture. Leave the seed empty for new numbers each time.

🔬
Experiments to Try

(1) Compare normal and truncated_normal with the same stddev. See the tails cut off at ±2 stddev. (2) Set samples to 50, then 20000. Small samples look messy. Large samples match the true shape. (3) Type seed 42, sample twice. The picture does not change.


Section 08

Cheat Sheet

FunctionExampleDefault dtypeUse it for
tf.constanttf.constant([[1, 2]])inferredYour own data
tf.zeros / tf.onestf.zeros([3, 4])float32Biases, masks
tf.filltf.fill([2, 2], 5)from valueAny constant value
tf.zeros_liketf.zeros_like(x)same as xMatch another tensor
tf.eyetf.eye(3)float32Identity matrix
tf.rangetf.range(0, 10, 2)int32Indices, steps
tf.linspacetf.linspace(0., 1., 5)float32Plot points
tf.random.normaltf.random.normal([3])float32Weights, noise
tf.random.uniformtf.random.uniform([3])float32Weights, dropout masks

Section 09

Golden Rules

🧱 Creating Tensors — Rules to Remember
1
A tensor is a rectangle of values with one dtype. Jagged lists fail.
2
Convert NumPy data with dtype=tf.float32. NumPy's default float64 causes dtype errors later.
3
Constants are immutable. Use tf.Variable for values that change.
4
Use tf.zeros_like / tf.ones_like to match another tensor's shape and dtype.
5
Call tf.random.set_seed() at the top of your script, or use a tf.random.Generator, to make results repeatable.