TensorFlow
tensor construction
empty tensor
tf.concat
machine learning

constructing a TensorFlow tensor that behaves as empty when passed to tf.concat

Master System Design with Codemia

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

Introduction

To make a tensor behave like "nothing" in tf.concat, you do not need a special null tensor. You need a real tensor whose size is zero along the concat axis and whose other dimensions still match the tensors you are joining.

The Shape Rule Behind tf.concat

tf.concat requires all input tensors to have:

  • the same rank
  • the same shape on every non-concat axis
  • compatible dtype values

So an empty tensor is only "empty" in the useful sense if the concat axis has length 0.

Empty Tensor Along Axis 0

Suppose your normal tensors have shape (N, 4) and you concatenate along axis 0. The correct empty tensor has shape (0, 4).

python
1import tensorflow as tf
2
3empty = tf.zeros([0, 4], dtype=tf.float32)
4a = tf.ones([3, 4], dtype=tf.float32)
5b = tf.fill([2, 4], 7.0)
6
7result = tf.concat([empty, a, b], axis=0)
8
9print(result.shape)  # (5, 4)
10print(result.numpy())

The empty tensor contributes zero rows, which is exactly what you want.

Empty Tensor Along Axis 1

If you concatenate columns instead of rows, the zero must move to axis 1.

python
1import tensorflow as tf
2
3x = tf.ones([5, 3], dtype=tf.float32)
4empty_columns = tf.zeros([5, 0], dtype=tf.float32)
5
6result = tf.concat([x, empty_columns], axis=1)
7
8print(result.shape)  # (5, 3)

This works because:

  • rank matches
  • row count still matches
  • the concat axis has zero width

Why tf.constant([]) Often Fails

Beginners often try:

python
1import tensorflow as tf
2
3empty = tf.constant([], dtype=tf.float32)
4print(empty.shape)  # (0,)

This is only a rank-1 tensor. It works only when the other tensors are also rank 1 and the concat axis matches that shape. It does not magically adapt to higher-rank inputs.

For example, this fails:

python
1import tensorflow as tf
2
3x = tf.ones([3, 4], dtype=tf.float32)
4empty = tf.constant([], dtype=tf.float32)
5
6# rank mismatch
7# tf.concat([x, empty], axis=0)

So the right question is not "How do I create an empty TensorFlow tensor?" It is "What exact empty shape matches this concat operation?"

Dynamic Shapes

When some dimensions are only known at runtime, build the empty tensor from the input tensor shape.

python
1import tensorflow as tf
2
3x = tf.ones([5, 3], dtype=tf.float32)
4rows = tf.shape(x)[0]
5
6empty_columns = tf.zeros([rows, 0], dtype=x.dtype)
7result = tf.concat([x, empty_columns], axis=1)
8
9print(result)

This pattern is useful inside tf.function or model code where static Python integers are not always available.

When a Conditional Is Clearer

Sometimes using an empty placeholder is technically valid but semantically awkward. If the presence of an extra tensor is genuinely optional, a branch may express the logic better:

python
1import tensorflow as tf
2
3base = tf.ones([2, 3], dtype=tf.float32)
4extra = tf.fill([2, 2], 9.0)
5use_extra = tf.constant(False)
6
7result = tf.cond(
8    use_extra,
9    lambda: tf.concat([base, extra], axis=1),
10    lambda: base,
11)
12
13print(result)

This avoids building a fake empty tensor when the business logic is really conditional.

Dtype Still Matters

Even if the tensor is empty on the concat axis, the dtype must still match:

python
1import tensorflow as tf
2
3x = tf.ones([2, 2], dtype=tf.float32)
4empty = tf.zeros([0, 2], dtype=tf.float32)
5
6print(tf.concat([empty, x], axis=0))

If empty were int32 and x were float32, the concat would fail before shape even became the interesting part.

Common Pitfalls

The most common mistake is creating a rank-1 empty tensor with tf.constant([]) and expecting it to work for every concat. It does not.

Another issue is putting the zero on the wrong axis. If you concatenate on axis 1, then axis 1 should be zero-length, not axis 0.

People also forget dtype compatibility. An empty tensor still has a real dtype and must match the other inputs.

Summary

  • An "empty" concat input is just a normal tensor with zero length on the concat axis.
  • The tensor must still match rank and all non-concat dimensions.
  • 'tf.constant([]) is only useful for rank-1 cases unless you reshape it correctly.'
  • Use dynamic shape construction when dimensions are known only at runtime.
  • If the input is conceptually optional, tf.cond may be clearer than forcing an empty placeholder.

Course illustration
Course illustration

All Rights Reserved.