PaddlePaddle/PaddleOCR · error · ValueError

scale values should be positive

Error message

scale values should be positive

What it means

CVRandomAffine requires scale to be a 2-element tuple/list of positive scale factors; any element <= 0 raises ValueError at construction. Scale factors are multiplicative (1.0 = no scaling), so zero or negative magnitudes are meaningless for the random affine sampler.

Source

Thrown at ppocr/data/imaug/abinet_aug.py:107

        assert degrees >= 0, "degree must be positive."
        self.degrees = degrees

        if translate is not None:
            assert (
                isinstance(translate, (tuple, list)) and len(translate) == 2
            ), "translate should be a list or tuple and it must be of length 2."
            for t in translate:
                if not (0.0 <= t <= 1.0):
                    raise ValueError("translation values should be between 0 and 1")
        self.translate = translate

        if scale is not None:
            assert (
                isinstance(scale, (tuple, list)) and len(scale) == 2
            ), "scale should be a list or tuple and it must be of length 2."
            for s in scale:
                if s <= 0:
                    raise ValueError("scale values should be positive")
        self.scale = scale

        if shear is not None:
            if isinstance(shear, numbers.Number):
                if shear < 0:
                    raise ValueError(
                        "If shear is a single number, it must be positive."
                    )
                self.shear = [shear]
            else:
                assert isinstance(shear, (tuple, list)) and (
                    len(shear) == 2
                ), "shear should be a list or tuple and it must be of length 2."
                self.shear = shear
        else:
            self.shear = shear

    def _get_inverse_affine_matrix(self, center, angle, translate, scale, shear):

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Use two positive multiplicative factors, e.g. scale=(0.8, 1.2).
  2. If expressing percentages, convert to fractions (50% -> 0.5).
  3. Add a config sanity check that both elements are > 0 before training starts.

Example fix

# before
CVRandomAffine(degrees=10, scale=(0.5, 0))   # ValueError
# after
CVRandomAffine(degrees=10, scale=(0.8, 1.2))
Defensive patterns

Strategy: validation

Validate before calling

def valid_scale(s) -> bool:
    return (s is None
            or (isinstance(s, (tuple, list)) and len(s) == 2
                and all(x > 0 for x in s)))

Type guard

def is_valid_scale(v) -> bool:
    return v is None or (isinstance(v, (tuple, list)) and len(v) == 2 and all(x > 0 for x in v))

Prevention

When it happens

Trigger: CVRandomAffine(degrees=10, scale=(0.5, 0)) or scale=(-1.0, 1.0); also passing scale=0 (a bare number fails the tuple/list assertion before this, but a list containing 0 hits this error).

Common situations: Typing scale=(0, 1.0) intending 'range from zero'; sign typos; porting configs where scale was expressed as percentages (e.g. (50, 150)) which are valid positive numbers but semantically wrong.

Related errors


AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14). Data as JSON: /api/errors/a93bba6960c57060. Report an issue: GitHub.