microsoft/qlib · error · NotImplementedError
loss {} is not supported!
Error message
loss {} is not supported! What it means
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).
Source
Thrown at qlib/contrib/model/pytorch_nn.py:128
f"\nearly_stop_rounds : {early_stop_rounds}"
f"\neval_steps : {eval_steps}"
f"\noptimizer : {optimizer}"
f"\nloss_type : {loss}"
f"\nseed : {seed}"
f"\ndevice : {self.device}"
f"\nuse_GPU : {self.use_gpu}"
f"\nweight_decay : {weight_decay}"
f"\nenable data parall : {self.data_parall}"
f"\npt_model_uri: {pt_model_uri}"
f"\npt_model_kwargs: {pt_model_kwargs}"
)
if self.seed is not None:
np.random.seed(self.seed)
torch.manual_seed(self.seed)
if loss not in {"mse", "binary"}:
raise NotImplementedError("loss {} is not supported!".format(loss))
self._scorer = mean_squared_error if loss == "mse" else roc_auc_score
if init_model is None:
self.dnn_model = init_instance_by_config({"class": pt_model_uri, "kwargs": pt_model_kwargs})
if self.data_parall:
self.dnn_model = DataParallel(self.dnn_model).to(self.device)
else:
self.dnn_model = init_model
self.logger.info("model:\n{:}".format(self.dnn_model))
self.logger.info("model size: {:.4f} MB".format(count_parameters(self.dnn_model)))
if optimizer.lower() == "adam":
self.train_optimizer = optim.Adam(self.dnn_model.parameters(), lr=self.lr, weight_decay=self.weight_decay)
elif optimizer.lower() == "gd":
self.train_optimizer = optim.SGD(self.dnn_model.parameters(), lr=self.lr, weight_decay=self.weight_decay)
else:View on GitHub (pinned to 79633dd950)
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}.
Example fix
# before model = DNNModelPytorch(loss="crossentropy", ...) # NotImplementedError # after model = DNNModelPytorch(loss="binary", ...) # binary classification # or regression: model = DNNModelPytorch(loss="mse", ...)
Defensive patterns
Strategy: validation
Validate before calling
assert loss in {"mse", "binary"}, "DNNModelPytorch supports only 'mse' and 'binary'"
model = DNNModelPytorch(loss=loss, ...) Type guard
def is_supported_dnn_loss(name: str) -> bool:
return name in {"mse", "binary"} Try / catch
try:
model = DNNModelPytorch(loss=loss, ...)
except NotImplementedError as e:
raise ValueError(f"{e} — use 'mse' (regression) or 'binary' (AUC-scored classification)") from e Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Trying to add new losses by string; classification setups passing 'cross_entropy' instead of 'binary'; regression users passing 'l2' instead of 'mse'.
Related errors
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/adddbc50d352867a.
Report an issue: GitHub.