PaddlePaddle/PaddleOCR · error · NotImplementedError

normalization layer [%s] is not found

Error message

normalization layer [%s] is not found

What it means

GA-SPIN/SPIN transformer (rectification network for scene text) builds its normalization layers from norm_type: 'BN' maps to BatchNorm2D and 'IN' to InstanceNorm2D. Any other value raises NotImplementedError because the localization network's conv stack cannot be constructed without a norm layer.

Source

Thrown at ppocr/modeling/transforms/gaspin_transformer.py:148

            loc_lr (float): learning rate of location network
            stn (bool): whether to use stn.

        """
        super(GA_SPIN_Transformer, self).__init__()
        self.nc = in_channels
        self.spt = True
        self.offsets = offsets
        self.stn = stn  # set to True in GA-SPIN, while set it to False in SPIN
        self.I_r_size = I_r_size
        self.out_channels = in_channels
        if norm_type == "BN":
            norm_layer = functools.partial(nn.BatchNorm2D, use_global_stats=True)
        elif norm_type == "IN":
            norm_layer = functools.partial(
                nn.InstanceNorm2D, weight_attr=False, use_global_stats=False
            )
        else:
            raise NotImplementedError(
                "normalization layer [%s] is not found" % norm_type
            )

        if self.spt:
            self.sp_net = SP_TransformerNetwork(in_channels, default_type)
            self.spt_convnet = nn.Sequential(
                # 32*100
                nn.Conv2D(in_channels, 32, 3, 1, 1, bias_attr=False),
                norm_layer(32),
                nn.ReLU(),
                nn.MaxPool2D(kernel_size=2, stride=2),
                # 16*50
                nn.Conv2D(32, 64, 3, 1, 1, bias_attr=False),
                norm_layer(64),
                nn.ReLU(),
                nn.MaxPool2D(kernel_size=2, stride=2),
                # 8*25
                nn.Conv2D(64, 128, 3, 1, 1, bias_attr=False),

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Set norm_type: "BN" or "IN" (exact case) in the Transform config
  2. If group norm is needed, extend the branch with functools.partial(nn.GroupNorm, num_groups=...)

Example fix

# before
Transform:
  name: GASPINTransformer
  norm_type: 'bn'
# after
Transform:
  name: GASPINTransformer
  norm_type: 'BN'
Defensive patterns

Strategy: validation

Validate before calling

assert transform_cfg['norm_type'] in ('BN', 'IN'), f"norm_type must be 'BN' or 'IN' (exact case), got {transform_cfg['norm_type']!r}"

Type guard

def valid_norm_type(t: str) -> bool:
    return t in ('BN', 'IN')

Prevention

When it happens

Trigger: Instantiating GASPINTransformer / SPINTransforme with norm_type other than 'BN' or 'IN' (e.g. 'bn' lowercase, 'GN', 'None').

Common situations: Hand-editing TPG/RARE-style configs; expecting case-insensitive matching (it is exact); porting configs from models that use 'bn' lowercase naming.

Related errors


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