keras-team/keras · error · ValueError
Input data in `NumpyArrayIterator` should have rank 4. You p
Error message
Input data in `NumpyArrayIterator` should have rank 4. You passed an array with shape {self.x.shape} What it means
NumpyArrayIterator requires a rank-4 array (batch, rows, cols, channels) or (batch, channels, rows, cols). Arrays of other ranks are rejected.
Source
Thrown at keras/src/legacy/preprocessing/image.py:616
"sorted by the label, you might want "
"to shuffle them."
)
if subset == "validation":
x = x[:split_idx]
x_misc = [np.asarray(xx[:split_idx]) for xx in x_misc]
if y is not None:
y = y[:split_idx]
else:
x = x[split_idx:]
x_misc = [np.asarray(xx[split_idx:]) for xx in x_misc]
if y is not None:
y = y[split_idx:]
self.x = np.asarray(x, dtype=self.dtype)
self.x_misc = x_misc
if self.x.ndim != 4:
raise ValueError(
"Input data in `NumpyArrayIterator` "
"should have rank 4. You passed an array "
f"with shape {self.x.shape}"
)
channels_axis = 3 if data_format == "channels_last" else 1
if self.x.shape[channels_axis] not in {1, 3, 4}:
warnings.warn(
f"NumpyArrayIterator is set to use the data format convention"
f' "{data_format}" (channels on axis {channels_axis})'
", i.e. expected either 1, 3, or 4 channels "
f"on axis {channels_axis}. "
f"However, it was passed an array with shape {self.x.shape}"
f" ({self.x.shape[channels_axis]} channels)."
)
if y is not None:
self.y = np.asarray(y)
else:
self.y = NoneView on GitHub (pinned to 7a34a03db6)
Solutions
- Reshape x to (N, H, W, C) e.g. x[..., np.newaxis] for grayscale
- For a single image use np.expand_dims(img, axis=0)
- Check data_format ('channels_last' default) matches your axis order
Example fix
// before gen.flow(x_train_flat, y_train) # (N, 784) // after x = x_train_flat.reshape(-1, 28, 28, 1) gen.flow(x, y_train)
Defensive patterns
Strategy: validation
Validate before calling
x = np.asarray(x) assert x.ndim == 4, x.shape
Type guard
def is_rank4(a): return np.asarray(a).ndim == 4
Try / catch
try: gen.flow(x, y) except ValueError as e: if 'rank 4' in str(e): x = x.reshape(x.shape[0], *x.shape[1:]) if x.ndim==3 else ...
Prevention
- Standardize pipelines to NHWC upfront
- Assert ndim==4 right after loading data
When it happens
Trigger: Passing a single image (rank 3), a flat vector of pixels (rank 2), or a batch of 5D video frames to gen.flow(x, ...).
Common situations: Forgetting np.expand_dims(x, 0) for a single image; loading raw MNIST flattened to (60000, 784); wrong data_format vs array layout.
Related errors
- Input to `.fit()` should have rank 4. Got array with shape:
- Found bounding_boxes['boxes'].shape={boxes_shape} and expect
- Found bounding_boxes['boxes'].shape={boxes_shape} and expect
- Expected `bounding_boxes['boxes']` to have rank 2 or 3, with
- Expected the input image to be rank 3 or 4. Received inputs.
AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25).
Data as JSON: /api/errors/679a82df79e0731e.
Report an issue: GitHub.