keras-team/keras · error · ValueError
FBetaScore expects 2D inputs with shape (batch_size, output_
Error message
FBetaScore 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
Raised from FBetaScore._build during update_state when inputs are rank 2 but the last dimension (output_dim / num_classes) is None, i.e. not statically known. The metric must allocate per-class state variables, so it needs a concrete class count.
Source
Thrown at keras/src/metrics/f_score_metrics.py:131
self.average = average
self.beta = beta
self.threshold = threshold
self.axis = None
self._built = False
if self.average != "micro":
self.axis = 0
def _build(self, y_true_shape, y_pred_shape):
if len(y_pred_shape) != 2 or len(y_true_shape) != 2:
raise ValueError(
"FBetaScore 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(
"FBetaScore 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]
if self.average != "micro":
init_shape = (num_classes,)
else:
init_shape = ()
def _add_zeros_variable(name):
return self.add_variable(
name=name,
shape=init_shape,
initializer=initializers.Zeros(),
dtype=self.dtype,View on GitHub (pinned to 7a34a03db6)
Solutions
- Pass tensors with statically-known last dim (e.g. TensorSpec([None, num_classes])).
- Build the metric with a fixed shape or update it outside jit-traced code on concrete tensors.
- Prefer model.compile(metrics=[...]) so Keras builds metrics from the model's output shape.
Example fix
# before
@tf.function
def step(x, y):
m.update_state(y, model(x)) # output dim unknown under trace
# after
m = keras.metrics.FBetaScore(beta=1.0, average='macro')
m.build((None, 10), (None, 10)) # fix the class dim, update on concrete tensors 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 static'
Type guard
def has_static_last_dim(t) -> bool:
return t.shape[-1] is not None Prevention
- Give TensorSpecs explicit last dims when tracing.
- Let model.compile build metrics rather than calling update_state inside jit.
When it happens
Trigger: Calling update_state inside tf.function/JAX jit traced with dynamic output shapes; a Functional model whose output shape is (batch, None); symbolic tensors with unspecified last dim.
Common situations: Custom train steps traced with jit; XLA/jit dynamic axes; building metrics from symbolic tensors instead of model.compile.
Related errors
- FBetaScore expects 2D inputs with shape (batch_size, output_
- `y_pred` must have rank 2 when `multi_label=True`. Found ran
- Invalid `average` argument value. Expected one of: {None, 'm
- Invalid `beta` argument value. It should be a Python float.
- Invalid `beta` argument value. It should be > 0. Received: b
AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25).
Data as JSON: /api/errors/15e54f1c2606e445.
Report an issue: GitHub.