keras-team/keras · error · ValueError

R2Score expects 2D inputs with shape (batch_size, output_dim

Error message

R2Score expects 2D inputs with shape (batch_size, output_dim). Received input shapes: y_pred.shape={y_pred_shape} and y_true.shape={y_true_shape}.

What it means

R2Score._build(), called from the first update_state, requires both y_true and y_pred to be rank-2 tensors of shape (batch_size, output_dim). If either input is rank 1 (shape (batch,)) the metric raises this ValueError before creating state variables.

Source

Thrown at keras/src/metrics/regression_metrics.py:443

            )
        if num_regressors < 0:
            raise ValueError(
                "Invalid value for argument `num_regressors`. "
                "Expected a value >= 0. "
                f"Received: num_regressors={num_regressors}"
            )
        self.class_aggregation = class_aggregation
        self.num_regressors = num_regressors
        self.num_samples = self.add_variable(
            shape=(),
            initializer=initializers.Zeros(),
            name="num_samples",
        )
        self._built = False

    def _build(self, y_true_shape, y_pred_shape):
        if len(y_pred_shape) != 2 or len(y_true_shape) != 2:
            raise ValueError(
                "R2Score expects 2D inputs with shape "
                "(batch_size, output_dim). Received input "
                f"shapes: y_pred.shape={y_pred_shape} and "
                f"y_true.shape={y_true_shape}."
            )
        if y_pred_shape[-1] is None or y_true_shape[-1] is None:
            raise ValueError(
                "R2Score expects 2D inputs with shape "
                "(batch_size, output_dim), with output_dim fully "
                "defined (not None). Received input "
                f"shapes: y_pred.shape={y_pred_shape} and "
                f"y_true.shape={y_true_shape}."
            )
        num_classes = y_pred_shape[-1]
        self.squared_sum = self.add_variable(
            name="squared_sum",
            shape=[num_classes],
            initializer=initializers.Zeros(),

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Expand dims on both inputs: keras.ops.expand_dims(t, -1) so shapes become (batch, 1).
  2. Fix the model to output shape (batch, 1) instead of (batch,).
  3. Store y_true with an explicit trailing output dimension.

Example fix

# before
r2.update_state(y_true, y_pred)  # both shape (batch,)

# after
r2.update_state(keras.ops.expand_dims(y_true, -1),
                keras.ops.expand_dims(y_pred, -1))  # (batch, 1)
Defensive patterns

Strategy: type-guard

Validate before calling

import keras.ops as ops
def ensure2d(t):
    return ops.expand_dims(t, -1) if len(t.shape) == 1 else t
y_true, y_pred = ensure2d(y_true), ensure2d(y_pred)

Type guard

def is_rank2(x) -> bool:
    return len(getattr(x, 'shape', ())) == 2

Prevention

When it happens

Trigger: metric.update_state(y_true, y_pred) where y_true or y_pred has rank 1 - common with single-output regression models that emit shape (batch,).

Common situations: A Dense(1) model whose output was squeezed, targets stored as flat arrays, or custom heads that reshape outputs to rank 1.

Related errors


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