keras-team/keras · error · ValueError
`patches` has unexpected rank for 3D reconstruction. Expecte
Error message
`patches` has unexpected rank for 3D reconstruction. Expected 4 (unbatched) or 5 (batched). Received shape: {patches.shape} What it means
The 3D reconstruction path requires patches of rank 4 (unbatched: flat, gD, gH, gW) or rank 5 (batched: B, flat, gD, gH, gW) after layout handling. Any other rank cannot be a 3D patch grid, so it raises before reshaping.
Source
Thrown at keras/src/ops/image.py:1362
patches = backend.numpy.transpose(patches, axes=(0, 2, 3, 4, 1))
else:
raise ValueError(
"`patches` has unexpected rank for 3D channels_first "
"reconstruction. Expected 4 (unbatched) or 5 (batched). "
f"Received shape: {patches.shape}"
)
result = _reconstruct_patches_3d(
patches, size, output_size, strides, padding, "channels_last"
)
if len(result.shape) == 4:
return backend.numpy.transpose(result, axes=(3, 0, 1, 2))
return backend.numpy.transpose(result, axes=(0, 4, 1, 2, 3))
pD, pH, pW = size
D, H, W = output_size
if len(patches.shape) not in (4, 5):
raise ValueError(
"`patches` has unexpected rank for 3D reconstruction. "
"Expected 4 (unbatched) or 5 (batched). "
f"Received shape: {patches.shape}"
)
_unbatched = False
if len(patches.shape) == 4:
_unbatched = True
patches = backend.numpy.expand_dims(patches, axis=0)
shp = ops.shape(patches)
B, gD, gH, gW = shp[0], shp[1], shp[2], shp[3]
static_flat = patches.shape[-1]
if static_flat is None:
C = shp[4] // (pD * pH * pW)
else:
if static_flat % (pD * pH * pW) != 0:
raise ValueError(View on GitHub (pinned to 7a34a03db6)
Solutions
- Use the 2D reconstruct path for 2D patches (size length 2, rank-3/4 patches)
- Ensure patches rank is 5 batched or 4 unbatched for 3D; add/remove batch axis with expand_dims/squeeze as needed
- Print patches.shape right before the call and match it to (B, flat, gD, gH, gW)
Example fix
# before reconstruct_patches(patches_2d, size=(8,8), output_size=(16,28,28)) # after reconstruct_patches(patches_2d, size=(8,8), output_size=(28,28))
Defensive patterns
Strategy: validation
Validate before calling
assert len(patches.shape) in (4, 5), f'unexpected rank {len(patches.shape)}'
assert len(size) == 3 and len(output_size) == 3 Type guard
def is_3d_patches(patches) -> bool:
return len(patches.shape) in (4, 5) Prevention
- Match 2D/3D call sites explicitly
- Check rank after dataset batching/squeezing steps
When it happens
Trigger: reconstruct_patches_3d reached via a rank-3 or rank-6 patches tensor, or 2D image patches (rank 4 but wrong semantics) passed with a 3-element size triggering the 3D branch.
Common situations: Calling the 3D path with 2D patches or vice versa; extra leading dims from a dataset batch; squeezing the wrong axis during preprocessing.
Related errors
- For `padding='same'`, `output_size` width ({W}) must be in t
- `padding='valid'` requires output_size to equal size * grid.
- Invalid `output_size`. Expected length 3 (D, H, W). Got: out
- `patches` has unexpected rank for 3D channels_first reconstr
- For `padding='same'`, `output_size` depth ({D}) must be in t
AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25).
Data as JSON: /api/errors/31e2c73866bdff32.
Report an issue: GitHub.