keras-team/keras · error · ValueError

The rank of `mean` must be less than or equal to the number

Error message

The rank of `mean` must be less than or equal to the number of axes ({len(self.axis)}). Received: mean shape {np.shape(mean)} for axis {self.axis}

What it means

Normalization replaces each kept axis with one statistic value, so mean (and variance) must have rank <= number of kept axes. __init__ raises when len(np.shape(mean)) > len(self.axis).

Source

Thrown at keras/src/layers/preprocessing/normalization.py:148

        # Set `mean` and `variance` if passed.
        if (mean is not None) != (variance is not None):
            raise ValueError(
                "When setting values directly, both `mean` and `variance` "
                f"must be set. Received: mean={mean} and variance={variance}"
            )
        if mean is not None:
            # Verify mean and variance have the same shape.
            if np.shape(mean) != np.shape(variance):
                raise ValueError(
                    "When setting values directly, `mean` and `variance` "
                    "must have the same shape. Received: "
                    f"mean shape {np.shape(mean)} and "
                    f"variance shape {np.shape(variance)}"
                )
            # Verify mean rank <= number of axes.
            if len(np.shape(mean)) > len(self.axis):
                raise ValueError(
                    "The rank of `mean` must be less than or equal to the "
                    f"number of axes ({len(self.axis)}). Received: "
                    f"mean shape {np.shape(mean)} for axis {self.axis}"
                )

    def build(self, input_shape):
        if input_shape is None:
            return

        ndim = len(input_shape)
        self._build_input_shape = input_shape

        if any(a < -ndim or a >= ndim for a in self.axis):
            raise ValueError(
                "All `axis` values must be in the range [-ndim, ndim). "
                f"Received inputs with ndim={ndim}, while axis={self.axis}"
            )

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Reduce stats to one value per kept axis (e.g. per-channel mean of shape (3,) for axis=-1)
  2. If you need per-pixel normalization, subtract the mean image yourself before the layer
  3. Pick axis values whose count matches the rank of your statistics arrays

Example fix

// before
mean_img = np.load('mean.npy')  # (224,224,3)
layer = Normalization(axis=-1, mean=mean_img, variance=var_img)
// after
layer = Normalization(axis=-1, mean=mean_img.mean((0,1)), variance=var_img.mean((0,1)))
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np
if mean is not None and len(np.shape(mean)) > len(axis_list):
    mean = mean.mean(tuple(range(mean.ndim - 1)))  # reduce to per-axis stats
# do the same for variance before constructing the layer

Prevention

When it happens

Trigger: Normalization(axis=-1) with a 2-D mean; Normalization(axis=[1,2]) with a rank-3 statistics tensor (e.g. a full-resolution mean image).

Common situations: Image pipelines passing a full HxWxC mean image instead of per-channel stats; expecting per-pixel normalization, which the layer does not support.

Related errors


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