keras-team/keras · error · ValueError

{name} must be an odd number. Received: {name}={factor}

Error message

{name} must be an odd number. Received: {name}={factor}

What it means

RandomGaussianBlur._set_kernel_size requires every kernel-size entry in a 2-element sequence to be an odd integer, because Gaussian blur kernels are symmetric around a center pixel. If either factor[0] or factor[1] is even, this ValueError is raised at construction.

Source

Thrown at keras/src/layers/preprocessing/image_preprocessing/random_gaussian_blur.py:79

        self._set_factor(factor)
        self.kernel_size = self._set_kernel_size(kernel_size, "kernel_size")
        self.sigma = self._set_factor_by_name(sigma, "sigma")
        self.value_range = value_range
        self.seed = seed
        self.generator = SeedGenerator(seed)

    def _set_kernel_size(self, factor, name):
        error_msg = f"{name} must be an odd number. Received: {name}={factor}"
        if isinstance(factor, (tuple, list)):
            if len(factor) != 2:
                error_msg = (
                    f"The `{name}` argument should be a number "
                    "(or a list of two numbers) "
                    f"Received: {name}={factor}"
                )
                raise ValueError(error_msg)
            if (factor[0] % 2 == 0) or (factor[1] % 2 == 0):
                raise ValueError(error_msg)
            lower, upper = factor
        elif isinstance(factor, (int, float)):
            if factor % 2 == 0:
                raise ValueError(error_msg)
            lower, upper = factor, factor
        else:
            raise ValueError(error_msg)

        return lower, upper

    def _set_factor_by_name(self, factor, name):
        error_msg = (
            f"The `{name}` argument should be a number "
            "(or a list of two numbers) "
            "in the range "
            f"[{self._FACTOR_BOUNDS[0]}, {self._FACTOR_BOUNDS[1]}]. "
            f"Received: factor={factor}"
        )

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Round each entry up to the nearest odd number, e.g. [5, 5] instead of [4, 4]
  2. Use odd sizes when parameterizing sweeps: size = 2 * k + 1
  3. Validate with a quick check before constructing: all(v % 2 == 1 for v in kernel_size)

Example fix

# before
layers.RandomGaussianBlur(kernel_size=[4, 4])
# after
layers.RandomGaussianBlur(kernel_size=[5, 5])
Defensive patterns

Strategy: validation

Validate before calling

ks = [5, 5]
assert all(k % 2 == 1 for k in ks), "kernel sizes must be odd"

Type guard

def all_odd_pair(v) -> bool:
    return isinstance(v, (tuple, list)) and len(v) == 2 and all(x % 2 == 1 for x in v)

Try / catch

try:
    layer = RandomGaussianBlur(kernel_size=ks)
except ValueError:
    layer = RandomGaussianBlur(kernel_size=[k + (k % 2 == 0) for k in ks])

Prevention

When it happens

Trigger: kernel_size=[4, 4], kernel_size=[2, 5], or kernel_size=[6, 3] passed to layers.RandomGaussianBlur().

Common situations: Doubling a kernel size during hyperparameter sweeps (3 -> 6) and landing on an even number; copying even sizes from conv-layer configs where even kernels are legal.

Related errors


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