Trainer#
Trainer orchestrates a run but trains nothing itself. It seeds the RNG,
calls setup() on the datamodule, prints the model table, optionally runs the
barren-plateau pre-flight, assembles the callback list, then hands off to a
training loop chosen by the active backend.
import pyqit
trainer = pyqit.Trainer(max_epochs=30, learning_rate=0.05)
history = trainer.fit(model, dm)
print(history.best_epoch, history.best_score)
trainer.validate(model, dm) # {"val_loss": ..., "val_acc": ...}
trainer.test(model, dm) # {"test_loss": ..., "test_acc": ...}
preds = trainer.predict(model, dm) # runs on the test split
Trainer.fit() returns a TrainingHistory holding train_loss,
val_loss, train_acc, val_acc and epoch_times, one entry per
epoch.
learning_rate is one float for every weight, or one per weight group. A
model sorts its weights into "quantum" (the QNodes’) and "classical"
(dense layers’), listed by model.weight_groups(), and each group gets its
own optimizer, so a hybrid can move its circuit angles slower than its dense
layers. A mapping must name exactly the groups the model has.
trainer = pyqit.Trainer(learning_rate={"quantum": 0.01, "classical": 0.1})
Seeding happens too late for weights#
Trainer(seed=...) covers training and the diagnostics, not weight
initialisation. Models draw their weights in __init__, so seed before you
build one:
pyqit.set_seed(42) # first
model = VQCClassifier(n_qubits=4) # then
The same ordering applies to set_backend(), which each object reads
once in its own __init__.
Settings a backend cannot honour#
Each loop declares what it cannot do, and Trainer validates that when
the loop is built, before any data is split. The PennyLane loop rejects
backend_kwargs, because it has no Lightning trainer to forward them to, and
warns on logger, because metrics still come back in the history. A rejected
setting raises. A warned one trains correctly.
Both checks measure against the signature defaults, so a Trainer built with defaults never complains.
Passing Lightning settings#
On the torch backend, backend_kwargs goes straight to
lightning.pytorch.Trainer:
pyqit.Trainer(
max_epochs=50,
backend_kwargs={"accelerator": "gpu", "devices": 1, "gradient_clip_val": 0.5},
)
Lightning’s constructor is not mirrored onto Trainer. It carries roughly
forty parameters, most of which a PennyLane optimizer loop cannot honour, and it
holds none of learning_rate, optimizer, loss_fn or batch_size
anyway. The accelerator defaults to "cpu", so a GPU runs only when you ask
for one.