keras-team/keras · error · ValueError
When class_id is provided, y_pred must be a 2D array with sh
Error message
When class_id is provided, y_pred must be a 2D array with shape (num_samples, num_classes), found shape: {y_pred.shape} What it means
When update_confusion_matrix_variables() is called with class_id, it slices one class column out of y_pred, which requires a 2D prediction tensor of shape (num_samples, num_classes). If y_pred is rank 1 (for example after top_k filtering or with a single-output model), this ValueError is raised.
Source
Thrown at keras/src/metrics/metrics_utils.py:474
f'Invalid keys: "{invalid_keys}". '
f'Valid variable key options are: "{list(ConfusionMatrix)}"'
)
y_pred, y_true = squeeze_or_expand_to_same_rank(y_pred, y_true)
if sample_weight is not None:
sample_weight = ops.expand_dims(
ops.cast(sample_weight, dtype=variable_dtype), axis=-1
)
_, sample_weight = squeeze_or_expand_to_same_rank(
y_true, sample_weight, expand_rank_1=False
)
if top_k is not None:
y_pred = _filter_top_k(y_pred, top_k)
if class_id is not None:
if len(y_pred.shape) == 1:
raise ValueError(
"When class_id is provided, y_pred must be a 2D array "
"with shape (num_samples, num_classes), found shape: "
f"{y_pred.shape}"
)
# Preserve dimension to match with sample_weight
y_true = y_true[..., class_id, None]
y_pred = y_pred[..., class_id, None]
if thresholds_distributed_evenly:
return _update_confusion_matrix_variables_optimized(
variables_to_update,
y_true,
y_pred,
thresholds,
multi_label=multi_label,
sample_weights=sample_weight,
label_weights=label_weights,View on GitHub (pinned to 7a34a03db6)
Solutions
- Reshape y_pred to (batch, 1) with keras.ops.expand_dims(y_pred, -1) before update_state, or make the model output 2D.
- For binary classification, drop class_id and use the default thresholded metric on the single output.
- If using top_k with class_id, verify the post-filter y_pred still has rank 2.
Example fix
# before metric = keras.metrics.Precision(class_id=0) metric.update_state(y_true, y_pred) # y_pred shape (batch,) # after metric.update_state(y_true, keras.ops.expand_dims(y_pred, -1)) # (batch, 1)
Defensive patterns
Strategy: type-guard
Validate before calling
import keras.ops as ops y_pred2 = ops.expand_dims(y_pred, -1) if len(y_pred.shape) == 1 else y_pred
Type guard
def is_rank2(x) -> bool:
return len(getattr(x, 'shape', ())) == 2 Prevention
- Always feed (batch, num_classes) predictions when using class_id.
- Check model.output_shape before compiling with class_id metrics.
When it happens
Trigger: Calling with class_id=k while y_pred has rank 1, or combining top_k (which can reduce the prediction rank) with class_id on single-output models.
Common situations: Using Precision(class_id=1) or Recall(class_id=0) on a model whose output shape is (batch,) instead of (batch, num_classes) - typical for single-sigmoid-output binary classifiers.
Related errors
- R2Score expects 2D inputs with shape (batch_size, output_dim
- R2Score expects 2D inputs with shape (batch_size, output_dim
- Architecture configuration does not match {weights_name} var
- Model name "{name}" does not match weights variant "{weights
- DenseNet does not support the `channels_first` image data fo
AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25).
Data as JSON: /api/errors/eae8eeed7fff6b67.
Report an issue: GitHub.