{"record":{"id":"c1c44494509124b6","repo":"PaddlePaddle/PaddleOCR","slug":"main-loss-type-in-balanceloss-can-only-be-one-of","errorCode":null,"errorMessage":"main_loss_type in BalanceLoss() can only be one of {}","messagePattern":"main_loss_type in BalanceLoss\\(\\) can only be one of (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"ppocr/losses/det_basic_loss.py","lineNumber":74,"sourceCode":"        if self.main_loss_type == \"CrossEntropy\":\n            self.loss = nn.CrossEntropyLoss()\n        elif self.main_loss_type == \"Euclidean\":\n            self.loss = nn.MSELoss()\n        elif self.main_loss_type == \"DiceLoss\":\n            self.loss = DiceLoss(self.eps)\n        elif self.main_loss_type == \"BCELoss\":\n            self.loss = BCELoss(reduction=\"none\")\n        elif self.main_loss_type == \"MaskL1Loss\":\n            self.loss = MaskL1Loss(self.eps)\n        else:\n            loss_type = [\n                \"CrossEntropy\",\n                \"DiceLoss\",\n                \"Euclidean\",\n                \"BCELoss\",\n                \"MaskL1Loss\",\n            ]\n            raise Exception(\n                \"main_loss_type in BalanceLoss() can only be one of {}\".format(\n                    loss_type\n                )\n            )\n\n    def forward(self, pred, gt, mask=None):\n        \"\"\"\n        The BalanceLoss for Differentiable Binarization text detection\n        args:\n            pred (variable): predicted feature maps.\n            gt (variable): ground truth feature maps.\n            mask (variable): masked maps.\n        return: (variable) balanced loss\n        \"\"\"\n        positive = gt * mask\n        negative = (1 - gt) * mask\n\n        positive_count = int(positive.sum())","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/ppocr/losses/det_basic_loss.py#L56-L92","documentation":"BalanceLoss dispatches its internal main loss on the main_loss_type string, supporting exactly 'CrossEntropy', 'DiceLoss', 'Euclidean', 'BCELoss' and 'MaskL1Loss'. Any other string raises a generic Exception listing the allowed values. This happens in __init__, so the error fires as soon as the loss layer is built.","triggerScenarios":"BalanceLoss(main_loss_type='focal_loss'), 'bce' (wrong casing), or any unsupported name during model construction; commonly configured via the detection config's Loss section.","commonSituations":"Editing a DB/DB++ YAML and typing a lowercase or abbreviated loss name, or assuming a loss supported by another head (e.g. 'FocalLoss') is available here.","solutions":["Use one of the five exact names: 'CrossEntropy', 'DiceLoss', 'Euclidean', 'BCELoss', 'MaskL1Loss'","Fix the main_loss_type value in the detection config's BalanceLoss block (watch casing)","If you need focal-style behavior, use balance_loss=True with BCELoss rather than inventing a type name"],"exampleFix":"# before\nBalanceLoss(main_loss_type='bce')\n\n# after\nBalanceLoss(main_loss_type='BCELoss')","handlingStrategy":"validation","validationCode":"BALANCE_LOSS_TYPES = {'CrossEntropy', 'DiceLoss', 'Euclidean', 'BCELoss', 'MaskL1Loss'}\nassert main_loss_type in BALANCE_LOSS_TYPES, f'main_loss_type must be one of {sorted(BALANCE_LOSS_TYPES)}'","typeGuard":"def is_balance_loss_type(t: str) -> bool:\n    return t in {'CrossEntropy', 'DiceLoss', 'Euclidean', 'BCELoss', 'MaskL1Loss'}","tryCatchPattern":null,"preventionTips":["Keep an explicit set of supported loss names beside your config code and assert membership at startup","Names are case-sensitive: match the exact CamelCase in the error's list","Validate configs in CI by instantiating the model once"],"tags":["config","loss","text-detection","enum-value"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}