keras-team/keras · error · ValueError
ConvNeXt does not support the `channels_first` image data fo
Error message
ConvNeXt does not support the `channels_first` image data format. Switch to `channels_last` by editing your local config file at ~/.keras/keras.json
What it means
Internal guard in _extract_patches_2d: after the public wrapper normalized types, the 2D path requires an int or a length-2 tuple/list. A length-3 tuple reaching here means a 3D size was supplied to the 2D extractor (or extract_patches_2d was called directly), which cannot be interpreted.
Source
Thrown at keras/src/applications/convnext.py:395
the 4D tensor output of the last convolutional layer.
- `avg` means that global average pooling will be applied
to the output of the last convolutional layer,
and thus the output of the model will be a 2D tensor.
- `max` means that global max pooling will be applied.
classes: optional number of classes to classify images into,
only to be specified if `include_top` is `True`,
and if no `weights` argument is specified.
classifier_activation: A `str` or callable.
The activation function to use
on the "top" layer. Ignored unless `include_top=True`.
Set `classifier_activation=None` to return the logits
of the "top" layer.
Returns:
A model instance.
"""
if backend.image_data_format() == "channels_first":
raise ValueError(
"ConvNeXt does not support the `channels_first` image data "
"format. Switch to `channels_last` by editing your local "
"config file at ~/.keras/keras.json"
)
if not (weights in {"imagenet", None} or file_utils.exists(weights)):
raise ValueError(
"The `weights` argument should be either "
"`None` (random initialization), `imagenet` "
"(pre-training on ImageNet), "
"or the path to the weights file to be loaded."
)
if weights == "imagenet" and include_top and classes != 1000:
raise ValueError(
'If using `weights="imagenet"` with `include_top=True`, '
"`classes` should be 1000. "
f"Received classes={classes}"
)View on GitHub (pinned to 7a34a03db6)
Solutions
- Use a 2-element size (or int) for 2D images; reserve length-3 tuples for volumes
- Dispatch on image rank: ndim==4 -> size2d, ndim==5 -> size3d, instead of one shared size
- Update stale calls to the private _extract_patches_2d that still pass 3D sizes from before a refactor
Example fix
before: extract_patches_2d(imgs, size=(4, 4, 4)) -> TypeError; after: extract_patches_2d(imgs, size=(4, 4))
Defensive patterns
Strategy: validation
Validate before calling
if images.ndim == 4 and not (isinstance(size, int) or len(size) == 2):
size = size[:2] # or raise: 2D path needs a 2-element size Type guard
def is_2d_size(size) -> bool:
return isinstance(size, int) or (isinstance(size, (tuple, list)) and len(size) == 2) Prevention
- Dispatch 2D vs 3D on input rank and pick size accordingly
- Do not call private _extract_patches_* helpers from user code
- Keep one source of truth for patch size per modality
When it happens
Trigger: Calling the private/public 2D extractor with a 3-element size, e.g. extract_patches(images, size=(2, 2, 2)) on 4D images; invoking keras.src.ops.image.extract_patches_2d directly with a 3D patch spec; branching code that reuses one size variable for both 2D and 3D inputs.
Common situations: A pipeline that handles both MRI volumes and 2D slices with a single config-driven size; refactors where extract_patches was split into 2D/3D paths and the dispatch condition on image rank was inverted or removed.
Related errors
- Unknown activation function '{activation}' cannot be seriali
- Could not interpret activation function identifier: {identif
- If using `weights="imagenet"` with `include_top=True`, `clas
- The `weights` argument should be either `None` (random initi
- If using `weights` as `"imagenet"` with `include_top` as tru
AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25).
Data as JSON: /api/errors/94b91f89727f2d8f.
Report an issue: GitHub.