keras-team/keras · error · ValueError

Unexpected bias dimensions {len(bias_shape)}. Expected it to

Error message

Unexpected bias dimensions {len(bias_shape)}. Expected it to be 1 or {ndim(x) - 1} dimensions

What it means

bias_add() requires the bias tensor to be rank 1 (one scalar per channel) or exactly ndim(x)-1 (one bias per non-batch dimension, the Convolution2DFlipout-style full bias case). Any other rank is rejected because there is no unambiguous way to broadcast it against x under the chosen data_format.

Source

Thrown at keras/src/legacy/backend.py:246

            x.assign(value)


@keras_export("keras._legacy.backend.batch_normalization")
def batch_normalization(x, mean, var, beta, gamma, axis=-1, epsilon=1e-3):
    """DEPRECATED."""
    return tf.nn.batch_normalization(x, mean, var, beta, gamma, epsilon)


@keras_export("keras._legacy.backend.bias_add")
def bias_add(x, bias, data_format=None):
    """DEPRECATED."""
    if data_format is None:
        data_format = backend.image_data_format()
    if data_format not in {"channels_first", "channels_last"}:
        raise ValueError(f"Unknown data_format: {data_format}")
    bias_shape = bias.shape
    if len(bias_shape) != 1 and len(bias_shape) != ndim(x) - 1:
        raise ValueError(
            f"Unexpected bias dimensions {len(bias_shape)}. "
            f"Expected it to be 1 or {ndim(x) - 1} dimensions"
        )

    if len(bias_shape) == 1:
        if data_format == "channels_first":
            return tf.nn.bias_add(x, bias, data_format="NCHW")
        return tf.nn.bias_add(x, bias, data_format="NHWC")
    if ndim(x) in (3, 4, 5):
        if data_format == "channels_first":
            bias_reshape_axis = (1, bias_shape[-1]) + bias_shape[:-1]
            return x + reshape(bias, bias_reshape_axis)
        return x + reshape(bias, (1,) + bias_shape)
    return tf.nn.bias_add(x, bias)


@keras_export("keras._legacy.backend.binary_crossentropy")
def binary_crossentropy(target, output, from_logits=False):

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Reshape the bias to rank 1: bias = keras.ops.reshape(bias, (-1,)) when it is one value per channel
  2. Or reshape to rank ndim(x)-1 matching x's non-batch dims if you genuinely need spatial biases
  3. Check that x actually has its batch dimension (expand_dims) and that you passed bias, not the kernel

Example fix

// before
out = K.bias_add(x, bias)  # bias.shape=(1, 3), x rank 4 -> ValueError

// after
out = K.bias_add(x, keras.ops.reshape(bias, (-1,)))  # bias.shape=(3,)
Defensive patterns

Strategy: validation

Validate before calling

assert len(bias.shape) == 1 or len(bias.shape) == len(x.shape) - 1, f'bias rank {len(bias.shape)} invalid for x rank {len(x.shape)}'

Type guard

def valid_bias(x, bias) -> bool:
    r = len(bias.shape)
    return r == 1 or r == len(x.shape) - 1

Try / catch

except ValueError as e:
    if 'bias dimensions' in str(e):
        out = K.bias_add(x, keras.ops.reshape(bias, (-1,)), data_format=fmt)
    else:
        raise

Prevention

When it happens

Trigger: bias_add(x, bias) where bias.shape has rank >= 2 and != ndim(x)-1 — e.g. x of rank 4 (batch of images) with a rank-2 bias (16, 3) instead of rank-1 (3,) or rank-3 (h, w, 3).

Common situations: Flattening or reshaping a per-channel bias vector into 2D; passing a kernel's weights instead of the bias vector; custom conv layers where x gained/lost a batch axis before bias_add is called.

Related errors


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