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), with output_dim fully defined (not None). Received input shapes: y_pred.shape={y_pred_shape} and y_true.shape={y_true_shape}.

What it means

Even with rank-2 inputs, R2Score needs output_dim (the last axis) statically known so it can create per-output state variables. If y_pred.shape[-1] or y_true.shape[-1] is None (a dynamic dimension), _build() raises this ValueError. This happens with symbolic KerasTensors whose feature dimension is undefined.

Source

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

        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(),
        )
        self.sum = self.add_variable(
            name="sum",
            shape=[num_classes],
            initializer=initializers.Zeros(),
        )
        self.total_mse = self.add_variable(

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Give the input a fully defined feature dimension: keras.Input(shape=(output_dim,)) or fix the producing layer to emit a known last axis.
  2. If output_dim genuinely varies, compute per-batch R-squared outside Keras metrics.
  3. For variable-length sequences, mask or pool to a fixed output_dim before the metric.

Example fix

# before
inputs = keras.Input(shape=(None,))  # undefined feature dim
model.compile(metrics=[keras.metrics.R2Score()])

# after
inputs = keras.Input(shape=(window_size,))
model.compile(metrics=[keras.metrics.R2Score()])
Defensive patterns

Strategy: validation

Validate before calling

assert y_pred.shape[-1] is not None and y_true.shape[-1] is not None, 'output_dim must be statically defined for R2Score'

Type guard

def has_static_output_dim(shape) -> bool:
    return shape[-1] is not None

Prevention

When it happens

Trigger: Passing tensors built from keras.Input(shape=(None,)) or layer outputs with an undefined feature dimension to R2Score, e.g. inside a Functional model compiled with metrics=[R2Score()].

Common situations: Time-series or variable-length inputs where keras.Input(shape=(None,)) is used; models built with dynamic axes on the feature dimension.

Related errors


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