{"record":{"id":"adddbc50d352867a","repo":"microsoft/qlib","slug":"loss-is-not-supported","errorCode":null,"errorMessage":"loss {} is not supported!","messagePattern":"loss (.+?) is not supported!","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"qlib/contrib/model/pytorch_nn.py","lineNumber":128,"sourceCode":"            f\"\\nearly_stop_rounds : {early_stop_rounds}\"\n            f\"\\neval_steps : {eval_steps}\"\n            f\"\\noptimizer : {optimizer}\"\n            f\"\\nloss_type : {loss}\"\n            f\"\\nseed : {seed}\"\n            f\"\\ndevice : {self.device}\"\n            f\"\\nuse_GPU : {self.use_gpu}\"\n            f\"\\nweight_decay : {weight_decay}\"\n            f\"\\nenable data parall : {self.data_parall}\"\n            f\"\\npt_model_uri: {pt_model_uri}\"\n            f\"\\npt_model_kwargs: {pt_model_kwargs}\"\n        )\n\n        if self.seed is not None:\n            np.random.seed(self.seed)\n            torch.manual_seed(self.seed)\n\n        if loss not in {\"mse\", \"binary\"}:\n            raise NotImplementedError(\"loss {} is not supported!\".format(loss))\n        self._scorer = mean_squared_error if loss == \"mse\" else roc_auc_score\n\n        if init_model is None:\n            self.dnn_model = init_instance_by_config({\"class\": pt_model_uri, \"kwargs\": pt_model_kwargs})\n\n            if self.data_parall:\n                self.dnn_model = DataParallel(self.dnn_model).to(self.device)\n        else:\n            self.dnn_model = init_model\n\n        self.logger.info(\"model:\\n{:}\".format(self.dnn_model))\n        self.logger.info(\"model size: {:.4f} MB\".format(count_parameters(self.dnn_model)))\n\n        if optimizer.lower() == \"adam\":\n            self.train_optimizer = optim.Adam(self.dnn_model.parameters(), lr=self.lr, weight_decay=self.weight_decay)\n        elif optimizer.lower() == \"gd\":\n            self.train_optimizer = optim.SGD(self.dnn_model.parameters(), lr=self.lr, weight_decay=self.weight_decay)\n        else:","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/contrib/model/pytorch_nn.py#L110-L146","documentation":"DNNModelPytorch's constructor validates the loss parameter against {'mse','binary'} and raises NotImplementedError('loss {} is not supported!') otherwise. The choice also selects the scorer used for logging: mean_squared_error for 'mse' and roc_auc_score for 'binary' (so 'binary' requires 0/1 labels and probability-style model output).","triggerScenarios":"Instantiating DNNModelPytorch(loss=...) in qlib/contrib/model/pytorch_nn.py with a value outside {'mse','binary'} — e.g. 'mae', 'crossentropy', 'bce'. Raised in __init__, before the pt model is built.","commonSituations":"Trying to add new losses by string; classification setups passing 'cross_entropy' instead of 'binary'; regression users passing 'l2' instead of 'mse'.","solutions":["Use loss='mse' for regression or loss='binary' for binary classification/AUC scoring.","For other losses, subclass DNNModelPytorch and override __init__ (skip/extend the check) and the train/loss logic as needed.","Ensure labels match: 'binary' feeds roc_auc_score, which requires both classes present and labels in {0,1}."],"exampleFix":"# before\nmodel = DNNModelPytorch(loss=\"crossentropy\", ...)  # NotImplementedError\n\n# after\nmodel = DNNModelPytorch(loss=\"binary\", ...)  # binary classification\n# or regression:\nmodel = DNNModelPytorch(loss=\"mse\", ...)","handlingStrategy":"validation","validationCode":"assert loss in {\"mse\", \"binary\"}, \"DNNModelPytorch supports only 'mse' and 'binary'\"\nmodel = DNNModelPytorch(loss=loss, ...)","typeGuard":"def is_supported_dnn_loss(name: str) -> bool:\n    return name in {\"mse\", \"binary\"}","tryCatchPattern":"try:\n    model = DNNModelPytorch(loss=loss, ...)\nexcept NotImplementedError as e:\n    raise ValueError(f\"{e} — use 'mse' (regression) or 'binary' (AUC-scored classification)\") from e","preventionTips":["Use 'mse' for regression, 'binary' for binary classification — there is no multi-class option.","'binary' scores with roc_auc_score: labels must be 0/1 with both classes present.","Subclass to extend the loss set; update the scorer consistently."],"tags":["pytorch","qlib","loss-function","dnn","config"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}