keras-team/keras · error · ValueError

`factor` argument cannot have an upper bound less than the l

Error message

`factor` argument cannot have an upper bound less than the lower bound. Received: factor={factor}

What it means

The deprecated RandomWidth layer is the width-domain twin of RandomHeight: `factor` is either a single number or a (lower, upper) tuple, and the constructor rejects any tuple whose upper bound is less than its lower bound (e.g. (0.9, 0.3)) because the layer samples uniformly from [width_lower, width_upper], undefined for an empty interval.

Source

Thrown at keras/src/legacy/layers.py:155

        return {**base_config, **config}


@keras_export("keras._legacy.layers.RandomWidth")
class RandomWidth(Layer):
    """DEPRECATED."""

    def __init__(self, factor, interpolation="bilinear", seed=None, **kwargs):
        super().__init__(**kwargs)
        self.seed_generator = backend.random.SeedGenerator(seed)
        self.factor = factor
        if isinstance(factor, (tuple, list)):
            self.width_lower = factor[0]
            self.width_upper = factor[1]
        else:
            self.width_lower = -factor
            self.width_upper = factor
        if self.width_upper < self.width_lower:
            raise ValueError(
                "`factor` argument cannot have an upper bound less than the "
                f"lower bound. Received: factor={factor}"
            )
        if self.width_lower < -1.0 or self.width_upper < -1.0:
            raise ValueError(
                "`factor` argument must have values larger than -1. "
                f"Received: factor={factor}"
            )
        self.interpolation = interpolation
        self.seed = seed

    def call(self, inputs, training=True):
        inputs = tf.convert_to_tensor(inputs, dtype=self.compute_dtype)

        def random_width_inputs(inputs):
            """Inputs width-adjusted with random ops."""
            inputs_shape = tf.shape(inputs)
            img_hd = inputs_shape[-3]

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Pass (lower, upper) in ascending order, e.g. RandomWidth(factor=(0.2, 0.4))
  2. Sort the pair defensively at construction: factor=tuple(sorted(pair))
  3. Prefer the modern keras.layers.RandomWidth with the same validated contract

Example fix

# before
layer = RandomWidth(factor=(0.4, 0.2))
# after
layer = RandomWidth(factor=(0.2, 0.4))
Defensive patterns

Strategy: validation

Validate before calling

lo, hi = tuple(factor) if isinstance(factor, (tuple, list)) else (-factor, factor)
assert lo <= hi, f'factor bounds crossed: {factor}'

Prevention

When it happens

Trigger: Constructing keras._legacy.layers.RandomWidth(factor=(0.9, 0.3)) or any (upper, lower)-ordered pair; also generated/serialized configs whose bounds are sorted descending.

Common situations: Hand-editing augmentation pipelines and swapping bounds; hyperparameter sweeps producing crossed intervals; porting from libraries with (max, min) argument order.

Related errors


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