tensorflow
placeholders
numpy
data-feeding
machine-learning

How do I feed Tensorflow placeholders with numpy arrays?

Master System Design with Codemia

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

Introduction

In TensorFlow 1-style graph code, NumPy arrays are passed into placeholders through the feed_dict argument of Session.run(). The essential rule is simple: the NumPy array must match the placeholder's expected dtype and shape, including batch dimensions, and the whole setup belongs to TensorFlow 1 compatibility mode rather than normal TensorFlow 2 eager code.

Basic Placeholder Feeding

In TensorFlow 1 style, a placeholder is a symbolic input node:

python
1import numpy as np
2import tensorflow as tf
3
4tf.compat.v1.disable_eager_execution()
5
6x = tf.compat.v1.placeholder(tf.float32, shape=[None, 3], name="x")
7w = tf.constant([[1.0], [2.0], [3.0]], dtype=tf.float32)
8y = tf.matmul(x, w)
9
10batch = np.array([
11    [1.0, 0.0, 1.0],
12    [2.0, 1.0, 0.0],
13], dtype=np.float32)
14
15with tf.compat.v1.Session() as sess:
16    result = sess.run(y, feed_dict={x: batch})
17    print(result)

The key in the feed dictionary is the placeholder tensor itself, and the value is the NumPy array you want TensorFlow to use for that run.

Match Shape and Dtype Carefully

The placeholder in the previous example has shape [None, 3], so the fed array must have three columns. The leading dimension is flexible because it represents batch size.

A quick debugging pattern is:

python
print(batch.shape)  # (2, 3)
print(batch.dtype)  # float32

If the placeholder expects tf.float32 and your NumPy array is float64, TensorFlow may raise a type error or force an implicit conversion that you did not intend.

Feeding Multiple Placeholders

Most training steps feed more than one placeholder at once, typically features and labels:

python
1import numpy as np
2import tensorflow as tf
3
4tf.compat.v1.disable_eager_execution()
5
6features = tf.compat.v1.placeholder(tf.float32, shape=[None, 2], name="features")
7labels = tf.compat.v1.placeholder(tf.float32, shape=[None, 1], name="labels")
8
9predictions = tf.reduce_sum(features, axis=1, keepdims=True)
10loss = tf.reduce_mean(tf.square(predictions - labels))
11
12x_np = np.array([[1.0, 2.0], [3.0, 4.0]], dtype=np.float32)
13y_np = np.array([[3.0], [7.0]], dtype=np.float32)
14
15with tf.compat.v1.Session() as sess:
16    loss_value = sess.run(loss, feed_dict={
17        features: x_np,
18        labels: y_np,
19    })
20    print(loss_value)

Every placeholder used by the requested tensor must be satisfied by the feed dictionary or by other graph operations.

Feeding by Tensor Name

Most code should use the placeholder object itself as the feed_dict key. In older graph-loading workflows, you may also see code that resolves a placeholder by name first and then feeds it.

Single Samples Still Need Batch Shape

A frequent mistake is feeding one example without its batch dimension.

Wrong shape for [None, 2]:

python
single = np.array([5.0, 6.0], dtype=np.float32)

Correct batched shape:

python
1single = np.array([5.0, 6.0], dtype=np.float32)
2single_batch = np.expand_dims(single, axis=0)
3
4print(single_batch.shape)  # (1, 2)

Even one example is still a batch of size one when the placeholder is batch-oriented.

Feeding During Training

A more realistic pattern is to feed placeholders into a training step:

python
1import numpy as np
2import tensorflow as tf
3
4tf.compat.v1.disable_eager_execution()
5
6x = tf.compat.v1.placeholder(tf.float32, shape=[None, 1])
7y_true = tf.compat.v1.placeholder(tf.float32, shape=[None, 1])
8
9w = tf.Variable([[0.0]], dtype=tf.float32)
10b = tf.Variable([0.0], dtype=tf.float32)
11y_pred = tf.matmul(x, w) + b
12
13loss = tf.reduce_mean(tf.square(y_pred - y_true))
14train_op = tf.compat.v1.train.GradientDescentOptimizer(0.01).minimize(loss)
15
16x_np = np.array([[1.0], [2.0], [3.0]], dtype=np.float32)
17y_np = np.array([[2.0], [4.0], [6.0]], dtype=np.float32)
18
19with tf.compat.v1.Session() as sess:
20    sess.run(tf.compat.v1.global_variables_initializer())
21    for _ in range(100):
22        sess.run(train_op, feed_dict={x: x_np, y_true: y_np})
23    print(sess.run([w, b]))

This is the standard TensorFlow 1 workflow that older tutorials refer to when they say "feed placeholders with NumPy."

TensorFlow 2 Equivalent

Modern TensorFlow usually avoids placeholders entirely. Instead, you pass tensors directly to functions or Keras models:

python
1import tensorflow as tf
2import numpy as np
3
4@tf.function
5def model(x):
6    w = tf.constant([[1.0], [2.0], [3.0]], dtype=tf.float32)
7    return tf.matmul(x, w)
8
9batch = np.array([[1.0, 0.0, 1.0]], dtype=np.float32)
10print(model(tf.convert_to_tensor(batch)).numpy())

For new code, this is usually the better approach. Placeholder feeding matters mainly when maintaining TensorFlow 1 graphs or compatibility code.

Common Pitfalls

The most common mistake is dtype mismatch, especially feeding NumPy's default float64 arrays into tf.float32 placeholders. Another common issue is forgetting the batch dimension for single examples, which produces shape errors even when the underlying data values are correct.

A third problem is mixing TensorFlow 1 graph mode and TensorFlow 2 eager assumptions in the same script. If you are using placeholders, make the execution mode explicit and stay consistent throughout the file.

Summary

  • Feed NumPy arrays into TensorFlow 1 placeholders with feed_dict.
  • Use the placeholder tensor itself as the dictionary key.
  • Match both dtype and shape, including batch dimensions.
  • Feed multiple placeholders together in the same Session.run() call when needed.
  • For new projects, prefer TensorFlow 2 tensor-argument or Keras input patterns instead of placeholders.

Course illustration
Course illustration

All Rights Reserved.