keras-team/keras · error · ValueError

Invalid images rank: expected rank 3 (single image) or rank

Error message

Invalid images rank: expected rank 3 (single image) or rank 4 (batch of images). Received: images.shape={images_shape}

What it means

This is the output-spec computation of the grayscale-to-RGB style image op (keras/src/ops/image.py auto_schedule/grayscale family): the images argument must be rank 3 (H, W, C) or rank 4 (N, H, W, C). Any other rank (e.g. rank 2 or rank 5) is rejected before channel logic runs.

Source

Thrown at keras/src/ops/image.py:23

from keras.src.backend import any_symbolic_tensors
from keras.src.ops.operation import Operation
from keras.src.ops.operation_utils import compute_conv_output_shape


class RGBToGrayscale(Operation):
    def __init__(self, data_format=None, *, name=None):
        super().__init__(name=name)
        self.data_format = backend.standardize_data_format(data_format)

    def call(self, images):
        return backend.image.rgb_to_grayscale(
            images, data_format=self.data_format
        )

    def compute_output_spec(self, images):
        images_shape = list(images.shape)
        if len(images_shape) not in (3, 4):
            raise ValueError(
                "Invalid images rank: expected rank 3 (single image) "
                "or rank 4 (batch of images). "
                f"Received: images.shape={images_shape}"
            )
        channels_axis = -1 if self.data_format == "channels_last" else -3
        channels = images_shape[channels_axis]
        if channels is not None and channels not in (1, 3):
            raise ValueError(
                "Invalid channel size: expected 3 (RGB) or 1 (Grayscale). "
                f"Received input with shape: images.shape={tuple(images_shape)}"
            )
        images_shape[channels_axis] = 1
        return KerasTensor(shape=images_shape, dtype=images.dtype)


@keras_export("keras.ops.image.rgb_to_grayscale")
def rgb_to_grayscale(images, data_format=None):
    """Convert RGB images to grayscale.

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Reshape input to rank 3 or 4: x = x[..., None] for (H,W) input or np.expand_dims(x, 0) to batch a single image
  2. If data is channels_first, pass data_format='channels_first' explicitly
  3. Verify no double batching (two stacked batch axes) in the data pipeline

Example fix

# before
y = op(images)  # images.shape=(224,224)

# after
images = images[..., None]  # (224,224,1)
y = op(images)
Defensive patterns

Strategy: validation

Validate before calling

assert len(images.shape) in (3, 4), f'bad rank: {images.shape}'

Type guard

def is_valid_image_rank(images) -> bool:
    return len(getattr(images, 'shape', ())) in (3, 4)

Try / catch

try:
    y = op(images)
except ValueError:
    images = images[..., None] if len(images.shape) == 2 else images
    y = op(images)

Prevention

When it happens

Trigger: Calling the op on a raw rank-2 array (no channel axis) or a rank-5 stack of batches; calling with data_format mismatch such that an extra axis is interpreted incorrectly.

Common situations: Loading grayscale masks stored as (H, W) without adding a channel dim; wrapping data in nested batches twice; mixing channels_first data passed without setting data_format.

Related errors


AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25). Data as JSON: /api/errors/557d5e3878f7b704. Report an issue: GitHub.