keras-team/keras · error · ValueError

The layer was built with input_shape={self._build_input_shap

Error message

The layer was built with input_shape={self._build_input_shape}, but adapt() is being called with data with an incompatible shape, data.shape={input_shape}

What it means

Once a Normalization layer is built, its kept-axis dimensions are fixed. adapt() on a built layer compares input_shape[d] to _build_input_shape[d] for each kept axis and raises when they differ, because the stored mean/variance buffers would no longer align with the data.

Source

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

                    f"{type(first_batch).__name__}. Ensure each yielded "
                    "element is array-like with a `.shape` attribute."
                )
            input_shape = tuple(input_shape)
            data = itertools.chain([first_batch], data_iter)
        else:
            raise TypeError(
                f"Unsupported data type: {type(data)}. `adapt` supports "
                f"`np.ndarray`, backend tensors, `tf.data.Dataset`, "
                f"`keras.utils.PyDataset`, and iterables of batches (e.g. "
                f"list, generator)."
            )

        if not self.built:
            self.build(input_shape)
        else:
            for d in self._keep_axis:
                if input_shape[d] != self._build_input_shape[d]:
                    raise ValueError(
                        "The layer was built with "
                        f"input_shape={self._build_input_shape}, "
                        "but adapt() is being called with data with "
                        f"an incompatible shape, data.shape={input_shape}"
                    )

        if isinstance(data, np.ndarray):
            total_mean = np.mean(data, axis=self._reduce_axis)
            total_var = np.var(data, axis=self._reduce_axis)
        elif backend.is_tensor(data):
            total_mean = ops.mean(data, axis=self._reduce_axis)
            total_var = ops.var(data, axis=self._reduce_axis)
        elif isinstance(data, (tf.data.Dataset, PyDataset)) or data_is_iterable:
            total_mean = ops.zeros(self._mean_and_var_shape)
            total_var = ops.zeros(self._mean_and_var_shape)
            total_count = 0

            steps = None

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Create and adapt a fresh Normalization layer for the new shape
  2. Select/reorder features so kept-axis dims match the original build shape
  3. If the shape truly changed, rebuild the whole model from the new adapted layer

Example fix

// before
norm.adapt(x_train)          # built with 10 features
norm.adapt(x_train_v2)       # 13 features -> ValueError
// after
norm = keras.layers.Normalization()
norm.adapt(x_train_v2)
Defensive patterns

Strategy: validation

Validate before calling

for d in layer._keep_axis:
    if input_shape[d] != layer._build_input_shape[d]:
        raise ValueError('shape drift; rebuild the layer')

Prevention

When it happens

Trigger: Calling layer.adapt(data2) whose kept-axis dims differ from the data (or manual build) that first built it, e.g. built on 10 features, adapting 13-feature data.

Common situations: Schema drift between training and serving features; reusing a layer across preprocessing versions; adapting validation data with extra columns.

Related errors


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