{"record":{"id":"ea6a9297247e6d9e","repo":"PaddlePaddle/PaddleOCR","slug":"normalization-layer-s-is-not-found","errorCode":null,"errorMessage":"normalization layer [%s] is not found","messagePattern":"normalization layer \\[(.+?)\\] is not found","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"ppocr/modeling/transforms/gaspin_transformer.py","lineNumber":148,"sourceCode":"            loc_lr (float): learning rate of location network\n            stn (bool): whether to use stn.\n\n        \"\"\"\n        super(GA_SPIN_Transformer, self).__init__()\n        self.nc = in_channels\n        self.spt = True\n        self.offsets = offsets\n        self.stn = stn  # set to True in GA-SPIN, while set it to False in SPIN\n        self.I_r_size = I_r_size\n        self.out_channels = in_channels\n        if norm_type == \"BN\":\n            norm_layer = functools.partial(nn.BatchNorm2D, use_global_stats=True)\n        elif norm_type == \"IN\":\n            norm_layer = functools.partial(\n                nn.InstanceNorm2D, weight_attr=False, use_global_stats=False\n            )\n        else:\n            raise NotImplementedError(\n                \"normalization layer [%s] is not found\" % norm_type\n            )\n\n        if self.spt:\n            self.sp_net = SP_TransformerNetwork(in_channels, default_type)\n            self.spt_convnet = nn.Sequential(\n                # 32*100\n                nn.Conv2D(in_channels, 32, 3, 1, 1, bias_attr=False),\n                norm_layer(32),\n                nn.ReLU(),\n                nn.MaxPool2D(kernel_size=2, stride=2),\n                # 16*50\n                nn.Conv2D(32, 64, 3, 1, 1, bias_attr=False),\n                norm_layer(64),\n                nn.ReLU(),\n                nn.MaxPool2D(kernel_size=2, stride=2),\n                # 8*25\n                nn.Conv2D(64, 128, 3, 1, 1, bias_attr=False),","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/ppocr/modeling/transforms/gaspin_transformer.py#L130-L166","documentation":"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.","triggerScenarios":"Instantiating GASPINTransformer / SPINTransforme with norm_type other than 'BN' or 'IN' (e.g. 'bn' lowercase, 'GN', 'None').","commonSituations":"Hand-editing TPG/RARE-style configs; expecting case-insensitive matching (it is exact); porting configs from models that use 'bn' lowercase naming.","solutions":["Set norm_type: \"BN\" or \"IN\" (exact case) in the Transform config","If group norm is needed, extend the branch with functools.partial(nn.GroupNorm, num_groups=...)"],"exampleFix":"# before\nTransform:\n  name: GASPINTransformer\n  norm_type: 'bn'\n# after\nTransform:\n  name: GASPINTransformer\n  norm_type: 'BN'","handlingStrategy":"validation","validationCode":"assert transform_cfg['norm_type'] in ('BN', 'IN'), f\"norm_type must be 'BN' or 'IN' (exact case), got {transform_cfg['norm_type']!r}\"","typeGuard":"def valid_norm_type(t: str) -> bool:\n    return t in ('BN', 'IN')","tryCatchPattern":null,"preventionTips":["Use exact-case 'BN'/'IN' in GASPIN/SPIN configs","Add a config validator that whitelists norm_type values"],"tags":["paddle","text-rectification","config","normalization"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}