keras-team/keras · error · ValueError
`patches` last dim ({static_flat}) is not divisible by prod(
Error message
`patches` last dim ({static_flat}) is not divisible by prod(size) ({pD * pH * pW}). Are `size` and the patches tensor consistent? What it means
In 3D reconstruction the channels count C is inferred by dividing the patches' last (flat) dimension by prod(size)=pD*pH*pW. If flat is not divisible by the patch volume, size and the patches tensor disagree, so C would not be an integer and it raises.
Source
Thrown at keras/src/ops/image.py:1380
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(
f"`patches` last dim ({static_flat}) is not divisible by "
f"prod(size) ({pD * pH * pW}). Are `size` and the patches "
f"tensor consistent?"
)
C = static_flat // (pD * pH * pW)
x = backend.numpy.reshape(patches, (B, gD, gH, gW, pD, pH, pW, C))
x = backend.numpy.transpose(x, axes=(0, 1, 4, 2, 5, 3, 6, 7))
x = backend.numpy.reshape(x, (B, gD * pD, gH * pH, gW * pW, C))
if padding == "same":
static_gD = patches.shape[1]
static_gH = patches.shape[2]
static_gW = patches.shape[3]
if isinstance(static_gD, int) and not (
static_gD * pD - pD < D <= static_gD * pD
):
raise ValueError(View on GitHub (pinned to 7a34a03db6)
Solutions
- Pass exactly the same size used in extract_patches
- Verify patches.shape[-1] == C * pD * pH * pW; solve for size if C is known
- If extra dims were concatenated into the flat dim, split them out first
Example fix
# before reconstruct_patches(patches, size=(2,8,8), output_size=out) # flat=768, 2*8*8=128 -> 768%128==0 ok; but with size=(4,8,8): 768%256!=0 # after size = (4, 8, 8) # match extraction; flat=1024 for C=4 reconstruct_patches(patches, size=size, output_size=out)
Defensive patterns
Strategy: validation
Validate before calling
flat = patches.shape[-1] assert flat is None or flat % (size[0]*size[1]*size[2]) == 0, 'size/patches mismatch'
Type guard
def size_matches_patches(patches, size) -> bool:
flat = patches.shape[-1]
return flat is None or flat % (size[0]*size[1]*size[2]) == 0 Prevention
- Persist the extraction patch size with the patches artifact
- Re-run extraction if the patching scheme changed
When it happens
Trigger: reconstruct_patches(patches, size=(pD,pH,pW), ...) where patches.shape[-1] % (pD*pH*pW) != 0, e.g. size=(4,8,8) (256) but flat dim 192, or passing a 2D-consistent size for 3D patches.
Common situations: Using a different patch size at reconstruction than at extraction; flattening extra features into the last dim; patches produced by a different layer/version with a different patching scheme.
Related errors
- For `padding='same'`, `output_size` width ({W}) must be in t
- `padding='valid'` requires output_size to equal size * grid.
- For `padding='same'`, `output_size` depth ({D}) must be in t
- `padding='valid'` requires output_size to equal size * grid.
- Invalid images rank: expected rank 3 (single image) or rank
AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25).
Data as JSON: /api/errors/ae5152b949189373.
Report an issue: GitHub.