Callbacks#
A pyqit callback implements up to three hooks, on_fit_start,
on_epoch_end and on_fit_end, each taking one LoopState. Write it
once and both backends honour it.
import pyqit
from pyqit.core import EarlyStopping, ModelCheckpoint
trainer = pyqit.Trainer(
max_epochs=100,
loss_fn="cross_entropy",
callbacks=[
EarlyStopping(monitor="val_loss", patience=3),
ModelCheckpoint(dirpath="ckpts", save_best=True, save_last=True),
],
)
history = trainer.fit(model, dm)
[EarlyStopping] Stopped at epoch 18 - val_loss did not improve for 3 epoch(s)
[Checkpoint] Restored best weights from epoch 15 (val_loss: 0.3721)
A checkpoint holds the optimizer state and history alongside the weights, so
ModelCheckpoint(resume_from=...) continues a run; its page shows how.
Available callbacks#
Request a stop after |
|
Save checkpoints, restore the best epoch's weights, or resume from one. |
|
Copy each epoch's metrics into a |
Why Lightning callbacks are rejected#
They are typed against Lightning’s hooks, so the PennyLane loop could only
ignore them. An ignored EarlyStopping hands back a fully trained model
without saying so, and that failure is invisible. Rejecting them at the door is
the louder option.
On the torch backend a shim reads Lightning’s callback_metrics into the same
metric names and forwards state.stop onto trainer.should_stop, so the
same callback object works on both sides.
Writing your own#
from pyqit.core import BaseCallback
class StopWhenConverged(BaseCallback):
def on_epoch_end(self, state):
if state.metrics["train_loss"] < 0.01:
state.stop = True
state carries the model, datamodule, history, reporter, epoch index and this
epoch’s metrics. state.stop is the one field a callback may write.
Base class for pyqit callbacks. |
|
Everything a callback may read, and the one flag it may write. |