DataModule#
DataModule holds the data and does nothing with it until setup()
runs. Trainer.fit and
Trainer.predict call setup() for you,
which is why properties like X_train raise before then.
import pyqit
from sklearn.datasets import make_moons
X, y = make_moons(n_samples=200, noise=0.1, random_state=0)
dm = pyqit.DataModule(X, y, normalize="minmax", batch_size=16)
What setup does, in order#
Split into train, val and test.
Normalize. This step is stateful, so the normalizer fits on train only and then applies to val and test.
minmax,zscore,l1andl2are built in.Prescale for the circuit. This step is stateless and the model’s embedding drives it, not the user.
Apply any
transform.
Prescaling explains why feature shaping is not your job. Each embedding names
the shaping it needs, such as zero-padding to n_qubits and multiplying by
pi, and setup() applies it. Input wider than the embedding takes raises.
The model class picks the embedding, so the model class decides the shape.
Repeated setup#
setup() returns early if it already ran, unless you pass force=True. Two
things sidestep that early return. batch_size applies every time, because it
only affects loader construction and never the split or the fitted normalizer,
so Trainer(batch_size=...) can override a datamodule you set up by hand.
encoder and n_qubits are overwritten only when actually supplied, so they
survive a later setup(force=True) that omits them.
Predicting on new rows#
A datamodule that has been fit holds the normalizer statistics, and new data has
to go through the same ones. for_prediction builds a predict-only datamodule
over new raw rows that carries the fitted normalizer, the encoder and the qubit
count from the one you trained on.
preds = trainer.predict(model, dm.for_prediction(X_new))
To do the same later without the training data, save the fitted DataModule
after fit. The file is a pickle of everything but the data: the
constructor settings, transforms, the fitted normalizer, the encoder and
n_qubits. load rebuilds a DataModule over new rows from it,
predict-only without targets and a training DataModule with the same settings
when targets are given. As with any pickle, load only files you wrote.
dm.save("ckpts/datamodule.pkl")
preds = trainer.predict(model, DataModule.load("ckpts/datamodule.pkl", X_new))
Handing Trainer.predict a fresh DataModule(X_new, ...) with
normalize= set raises instead, because a normalizer that was never fit
would either scale with the wrong statistics or not at all.
Building from tables#
dm = pyqit.DataModule.from_dataframe(df, label_col="target", normalize="zscore")
dm = pyqit.DataModule.from_csv("data.csv", label_col="target")