Using tf.unpack when first dimension of Variable is None
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
tf.unpack was the old name for what is now tf.unstack, and the core limitation has not changed: if you unstack along an axis, TensorFlow must know how many output tensors to create. When the first dimension is None, that count is not known statically, so a plain unstack along that axis becomes ambiguous. The fix is either to provide num explicitly or to redesign the computation so it does not require creating a Python list of unknown length.
Why None Causes Trouble Here
In TensorFlow shape notation, None usually means “this dimension is dynamic and will be known only at runtime.” That is perfectly fine for many operations. It is especially common for the batch dimension.
But unstack is different from an operation such as matrix multiplication. It does not just transform one tensor into another tensor. It creates multiple separate tensors. To do that, TensorFlow needs to know how many outputs to build.
So if you try to unstack along a dimension whose size is unknown, TensorFlow cannot determine the output list length at graph-construction time.
The Modern API Is tf.unstack
Older code may still mention tf.unpack, but the current name is tf.unstack.
This works because the size of axis 0 is known to be 3.
If the Size Is Known, Pass num
If the shape metadata is incomplete but you still know how many slices should exist, pass num explicitly.
The important point is that num tells TensorFlow how many outputs to create even if the static shape metadata on that axis is missing.
That only works when the axis length is actually fixed by the problem. If the batch size is truly variable, hardcoding num is the wrong fix.
Dynamic Batch Size Usually Means You Should Not Unstack Axis 0
A common source of confusion is trying to unstack the batch dimension. In many models the first dimension is None because the batch size should vary. Unstacking that axis would require TensorFlow to produce a Python list whose length depends on runtime input size.
That is usually a design smell. Instead of splitting the batch into separate tensors, keep the batch dimension intact and use tensor-aware operations such as:
- '
tf.map_fn' - vectorized tensor ops
- '
tf.TensorArrayin lower-level control-flow code'
For example, if the goal is to process each batch element independently, tf.map_fn is often the better fit.
This keeps the batch dimension dynamic without forcing a static output list length.
If You Need a Static Time Axis, Unstack That Axis Instead
In sequence models, sometimes the first dimension is the batch and the second dimension is a fixed number of time steps. In that case, unstacking the time axis may make sense if that axis length is known.
This works because the axis being unstacked has a known size of 5, even though the batch dimension remains dynamic.
The Practical Rule
Ask two questions before using tf.unstack.
- Which axis am I unstacking.
- Is that axis length statically known.
If the answer to the second question is no, then plain unstacking is usually the wrong tool unless you can honestly provide num.
Common Pitfalls
- Treating
tf.unpackas though it can always split a dynamic batch dimension into an arbitrary Python-length list. - Forgetting that
tf.unpackis legacy naming and thattf.unstackis the modern API. - Supplying a fake
numfor an axis whose runtime size is genuinely variable. - Unstacking axis
0out of habit when the real goal should have been a vectorized operation ortf.map_fn. - Confusing “dynamic tensor shapes are allowed” with “every op can ignore unknown output counts.”
Summary
- '
tf.unpackis the old name fortf.unstack.' - Unstacking requires TensorFlow to know how many output tensors to create.
- If the target axis size is unknown, you usually need to provide
numor choose a different operation. - Dynamic batch dimensions are a common reason unstacking axis
0fails. - When the length is truly dynamic,
tf.map_fnor vectorized tensor operations are usually a better design.

