Training, Execution, and Evaluation
QML models can be trained with a standard PyTorch loop or a reusable workflow composed of Trainer, gradient utilities, callbacks, and metrics.
Minimal training example
from unitarylab.library.qml.examples.classification import build_classifier, train_classifier
from unitarylab.library.qml.examples.datasets import load_toy_multiclass
dataset = load_toy_multiclass(samples_per_class=2, seed=0)
model = build_classifier("vqc", seed=0)
loss_history = train_classifier(
model, dataset.features, dataset.targets,
epochs=1, learning_rate=0.03,
)
print(loss_history)This is a complete PyTorch training workflow: the model has trainable parameters, the loss performs backpropagation, and the optimizer updates the parameters. Random initialization and data generation use explicit seeds.
Training components
from unitarylab.library.qml.engine import (
Trainer,
TorchOptimizer,
TorchScheduler,
EarlyStopping,
ModelCheckpoint,
evaluate,
save_parameters,
load_parameters,
)| Component | Purpose |
|---|---|
Trainer | Organize training steps, validation, history, and callbacks |
TorchOptimizer, TorchScheduler | Wrap PyTorch optimizers and learning-rate schedules |
EarlyStopping | Stop early based on a monitored metric |
ModelCheckpoint | Save best or periodic parameters |
NoiseScheduler | Adjust noise strength during training |
evaluate() | Compute loss and metrics on a dataset |
save_parameters(), load_parameters() | Save and restore parameters |
A trainer needs a model, objective, optimizer, and data. Classification tasks should use a binary or multiclass loss that matches the model output. For regression, prediction and target shapes must be broadcast-compatible or identical.
Gradient methods
| Method | Characteristics |
|---|---|
autograd_gradient() | Use backend or PyTorch automatic differentiation |
backend_vjp_loss_gradient() | Use backend vector–Jacobian products |
parameter_shift_gradient() / parameter_shift_jacobian() | Parameter-shift rules for gates with supported shift rules |
batched_parameter_shift_gradient() / parallel_parameter_shift_gradient() | Batch or parallelize parameter-shift circuits |
finite_difference_gradient() | General numerical differences with more evaluations |
spsa_gradient() | Stochastic approximation for many parameters or sampling noise |
mixed_parameter_gradient() | Combine gradient strategies by parameter type |
Parameter shift applies only to parameterized gates with known shift rules. Gradients with finite shots have statistical variation; fix the seed, record shots, and use repeated runs to estimate variance.
Metrics and objectives
from unitarylab.library.qml.metrics import multiclass_accuracy, mean_squared_error
from unitarylab.library.qml.objectives import SupervisedObjective, BornMachineNLLObjectiveClassification metrics include accuracy, precision, recall, F1, confusion matrix, and ROC AUC. Regression metrics include MAE, MSE, RMSE, and . Generative tasks can use Born-machine NLL, KL-divergence, or MMD objectives, along with QGAN generator and discriminator losses.
Diagnostics and persistence
gradient_variance_report(), per_sample_gradient_norms(), and trainability_report() diagnose vanishing gradients, per-sample gradient differences, and parameter-block trainability. Load checkpoints only from trusted sources; the model structure and parameter shapes must match those used when saving.
Resource recommendations
- Start with a very small batch and one epoch to check shapes, dtype, and device.
- State-vector memory grows exponentially with qubit count; parameter-shift gradients also add multiple circuit executions per step.
- Keep training, validation, and test sets separate; do not use test metrics for tuning.
- Record the random seed, backend, shots, dtype, and model structure for reproducibility.