keras-team/keras · error · ValueError

Target class id {max(target_class_ids)} is out of range, whi

Error message

Target class id {max(target_class_ids)} is out of range, which is [{0}, {num_classes}).

What it means

Raised by keras.metrics.IoU's __init__ when the largest id in target_class_ids is >= num_classes. Class ids index a num_classes-sized confusion matrix, so every target id must lie in [0, num_classes).

Source

Thrown at keras/src/metrics/iou_metrics.py:275

        target_class_ids,
        name=None,
        dtype=None,
        ignore_class=None,
        sparse_y_true=True,
        sparse_y_pred=True,
        axis=-1,
    ):
        super().__init__(
            name=name,
            num_classes=num_classes,
            ignore_class=ignore_class,
            sparse_y_true=sparse_y_true,
            sparse_y_pred=sparse_y_pred,
            axis=axis,
            dtype=dtype,
        )
        if max(target_class_ids) >= num_classes:
            raise ValueError(
                f"Target class id {max(target_class_ids)} "
                "is out of range, which is "
                f"[{0}, {num_classes})."
            )
        self.target_class_ids = list(target_class_ids)

    def result(self):
        """Compute the intersection-over-union via the confusion matrix."""
        sum_over_row = ops.cast(
            ops.sum(self.total_cm, axis=0), dtype=self.dtype
        )
        sum_over_col = ops.cast(
            ops.sum(self.total_cm, axis=1), dtype=self.dtype
        )
        true_positives = ops.cast(ops.diag(self.total_cm), dtype=self.dtype)

        # sum_over_row + sum_over_col =
        #     2 * true_positives + false_positives + false_negatives.

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Set num_classes to at least max(target_class_ids) + 1.
  2. Verify ids are 0-based; for 1..N labels either subtract 1 or set num_classes=N+1.
  3. Sanity-check in setup code: assert max(target_class_ids) < num_classes.

Example fix

# before
m = keras.metrics.IoU(num_classes=3, target_class_ids=[0, 1, 2, 3])

# after
m = keras.metrics.IoU(num_classes=4, target_class_ids=[0, 1, 2, 3])
# or score only classes 0-2 of a 4-class problem:
m = keras.metrics.IoU(num_classes=4, target_class_ids=[0, 1, 2])
Defensive patterns

Strategy: validation

Validate before calling

assert max(target_class_ids) < num_classes, (target_class_ids, num_classes)

Type guard

def ids_in_range(ids, num_classes) -> bool:
    return max(ids) < num_classes and min(ids) >= 0

Prevention

When it happens

Trigger: keras.metrics.IoU(num_classes=3, target_class_ids=[0, 1, 2, 5]); off-by-one num_classes=3 with target id 3; ids from a dataset with a larger label space than num_classes declares.

Common situations: num_classes from config while target ids cover more classes; forgetting ids are 0-based so max valid id is num_classes-1; including a background/ignore id beyond range.

Related errors


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