keras-team/keras · error · ValueError

Expected a square matrix. Received non-square input with sha

Error message

Expected a square matrix. Received non-square input with shape {a.shape}

What it means

Square-matrix Keras ops (cholesky, cholesky_inverse, det, eig, eigh) validate that the last two dimensions of each input are equal. The _assert_square helper unpacks a.shape[-2:] and raises when m != n, so any non-square trailing matrix, even inside a valid batch, is rejected before the op runs.

Source

Thrown at keras/src/ops/linalg.py:859

            raise ValueError(
                f"Expected input to have rank >= 1. Received scalar input {a}."
            )


def _assert_2d(*arrays):
    for a in arrays:
        if a.ndim < 2:
            raise ValueError(
                "Expected input to have rank >= 2. "
                f"Received input with shape {a.shape}."
            )


def _assert_square(*arrays):
    for a in arrays:
        m, n = a.shape[-2:]
        if m != n:
            raise ValueError(
                "Expected a square matrix. "
                f"Received non-square input with shape {a.shape}"
            )


def _assert_a_b_compat(a, b):
    if a.ndim == b.ndim:
        if a.shape[-2] != b.shape[-2]:
            raise ValueError(
                "Incompatible shapes between `a` and `b`. "
                "Expected `a.shape[-2] == b.shape[-2]`. "
                f"Received: a.shape={a.shape}, b.shape={b.shape}"
            )
    elif a.ndim == b.ndim - 1:
        if a.shape[-1] != b.shape[-1]:
            raise ValueError(
                "Incompatible shapes between `a` and `b`. "
                "Expected `a.shape[-1] == b.shape[-1]`. "

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Fix the construction of the matrix so the last two axes match, e.g. compute a square covariance via keras.ops.matmul(x, x, transpose_b=True).
  2. Inspect x.shape right before the call and correct upstream reshapes or concatenations that produced a rectangular trailing block.
  3. For PCA-style workflows, operate on the Gram/covariance matrix (n_features, n_features), not the raw (batch, features) data matrix.
  4. Add an explicit assert x.shape[-2] == x.shape[-1] before calling the op so failures surface with your own context.

Example fix

// before
from keras import ops
x = ops.ones((8, 5, 3))   # batch of 5x3 rectangles
evals = ops.eig(x)         # ValueError: non-square

// after
x = ops.ones((8, 5, 3))
cov = ops.matmul(x, x, transpose_b=True)  # (8, 5, 5), square per batch
evals = ops.eig(cov)
Defensive patterns

Strategy: validation

Validate before calling

from keras import ops

def ensure_square(x):
    sh = x.shape
    assert sh[-2] is None or sh[-2] == sh[-1], (
        f"expected square trailing dims, got {sh}")
    return x

evals = ops.eig(ensure_square(cov))

Type guard

import keras

def is_square_batch(x) -> bool:
    sh = x.shape
    return x.ndim >= 2 and sh[-2] is not None and sh[-2] == sh[-1]

Prevention

When it happens

Trigger: Calling keras.ops.eigh(x) or keras.ops.cholesky(x) with shape (3, 2) or a batch (B, 4, 5); computing a determinant or eigendecomposition of a matrix built by concatenation or reshaping to non-square; passing the output of a Dense layer with units != input features directly to these ops.

Common situations: Computing eigenvalues of a rectangular projection matrix; reusing NumPy code where np.linalg.eig fails similarly after migrating to keras.ops; a whitening/regularization layer calling eigh on activations whose last two dims differ; transposition mistakes leaving shape (m, n) with m != n.

Related errors


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