Skip to content

generic

eigenkit.torch.estimators.generic

Estimators that wrap any nn.Module.

They wrap any torch.nn.Module that you supply in a fit and predict interface compatible with scikit-learn, with the standard training and inference loops of the library. You must build the complete model, including any output head.

eigenkit.torch.estimators.generic.GenericRegressor

Bases: ModelAccessMixin, BaseQuantumRegressor

Regressor compatible with scikit-learn that wraps any torch.nn.Module.

You supply a complete model whose forward(X) accepts a float32 tensor of shape (batch, in_features) and returns a tensor of shape (batch, 1) or (batch,). For sequence models (for example a long short-term memory network), set sequence_input=True. The wrapper then passes a 3-D tensor of shape (batch, seq_len, in_features) as it is, instead of flattening it.

The wrapper trains the model with the standard train_loop() of the library, and returns the predictions as a float32 NumPy array.

Parameters:

Name Type Description Default
model Module

Any nn.Module. It must include its own output head.

required
in_features int | None

The expected number of features at each time step (the last dimension of the input). When it is given, fit raises an error if X.shape[-1] does not match. Pass None to skip the check.

None
sequence_input bool

If True, the estimator tells QuantumTimeSeriesRegressor that it expects a 3-D tensor of shape (batch, seq_len, in_features), so the windowed data must not be flattened. Default: False.

False
loss_func str | Callable

The loss: "mse", "mae", "huber", or any callable (output, target) -> scalar_tensor.

'mse'
huber_delta float

The threshold of the Huber loss. It is ignored for the other losses.

1.0
huber_reduction str

The reduction of the Huber loss: "mean" or "sum".

'mean'
lr float

The learning rate of the optimiser.

0.01
optimizer str

The name of the optimiser: "adam", "adamw", "rmsprop" or "sgd".

'adam'
optimizer_kwargs dict | None

Extra keyword arguments passed to the constructor of the optimiser.

None
epochs int

The number of full passes over the training data.

50
batch_size int

The size of each mini-batch.

32
show_progress bool

If True, a tqdm progress bar is shown during training.

True
random_state int | None

The seed, applied before the first training step.

42

Attributes:

Name Type Description
train_losses_

The list of the average loss of each epoch, set by fit().

validation_losses_

The list of the validation loss of each epoch, set by fit() when validation data is given.

Example
import numpy as np
from torch import nn
from eigenkit.torch.estimators import GenericRegressor
from eigenkit.torch.layers import Basic

rng = np.random.default_rng(0)
X_train, X_test = rng.normal(size=(30, 8)), rng.normal(size=(5, 8))
y_train = X_train.sum(axis=1)

# A plain PyTorch network.
net = nn.Sequential(nn.Linear(8, 16), nn.ReLU(), nn.Linear(16, 1))
reg = GenericRegressor(model=net, in_features=8, epochs=30)
reg.fit(X_train, y_train)
preds = reg.predict(X_test)

# A quantum layer with a classical head.
q = Basic(n_qubits=4, depth=2)
hybrid = nn.Sequential(q, nn.Linear(4, 1))
reg2 = GenericRegressor(model=hybrid, in_features=4)

accepts_sequence_input property

Whether the model expects a 3-D input (batch, seq_len, features).

fit(X, y, X_val=None, y_val=None)

Fit the model on training data.

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, in_features) for flat models, or (n_samples, seq_len, in_features) when sequence_input=True.

required
y ndarray

The real-valued targets, of shape (n_samples,).

required
X_val ndarray | None

Optional validation samples, used to compute the validation loss of each epoch.

None
y_val ndarray | None

Optional validation targets, used to compute the validation loss of each epoch.

None

Returns:

Type Description
'GenericRegressor'

This estimator, so that calls can be chained.

Raises:

Type Description
ValueError

If X.shape[-1] or X_val.shape[-1] differs from in_features, or if the output of the model does not have shape (batch,) or (batch, 1).

load(path, *, model=None, provider=None) classmethod

Load a fitted GenericRegressor from a .eigenkit bundle.

The architecture of the model cannot be rebuilt automatically, so you must give it. The saved weights are loaded into a copy of it.

Parameters:

Name Type Description Default
path str | Path

The path of the .eigenkit bundle.

required
model Module | None

An nn.Module with the same architecture as the one used in training. Its weights are not changed: the saved weights go into a deep copy, which is model_ of the loaded estimator.

None
provider ProviderSpec | None

It is ignored. It is kept so that the signature matches the other estimators.

None

Returns:

Type Description
'GenericRegressor'

The loaded estimator.

Raises:

Type Description
SerializationError

If model is not given.

TypeError

If the bundle holds a different class.

Example
from torch import nn
from eigenkit.torch.estimators import GenericRegressor

net = nn.Sequential(nn.Linear(8, 16), nn.ReLU(), nn.Linear(16, 1))
reg = GenericRegressor.load("checkpoint.eigenkit", model=net)

predict(X)

Predict the continuous targets of X. It returns a float32 array.

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, n_features).

required

Returns:

Type Description
ndarray

One prediction for each sample.

save(path)

Save a fitted model to a .eigenkit bundle.

The bundles of models that hold scikit-learn objects (QSVC, QSVR, the reservoir estimators and the time-series estimators) contain joblib pickles, so loading one can run code. Share them only with people who trust you.

Parameters:

Name Type Description Default
path str | Path

The path of the bundle. The suffix .eigenkit is added when it is missing.

required

eigenkit.torch.estimators.generic.GenericClassifier

Bases: ModelAccessMixin, BaseQuantumClassifier

Classifier compatible with scikit-learn that wraps any torch.nn.Module.

You supply a complete model whose forward(X) accepts a float32 tensor of shape (batch, in_features) and returns logits of shape (batch, n_classes). For sequence models (for example a long short-term memory network), set sequence_input=True. The wrapper then passes a 3-D tensor of shape (batch, seq_len, in_features) as it is, instead of flattening it.

The wrapper trains with CrossEntropyLoss and encodes the labels automatically.

Parameters:

Name Type Description Default
model Module

Any nn.Module. It must include its own classification head, which gives n_classes logits.

required
in_features int | None

The expected number of features at each time step (the last dimension of the input). When it is given, fit raises an error if X.shape[-1] does not match. Pass None to skip the check.

None
sequence_input bool

If True, the estimator tells QuantumTimeSeriesClassifier that it expects a 3-D tensor of shape (batch, seq_len, in_features), so the windowed data must not be flattened. Default: False.

False
n_classes int | None

The number of output classes. If None, it is inferred from the training labels. If it is given, it must equal the number of distinct labels in y.

None
lr float

The learning rate of the optimiser.

0.01
optimizer str

The name of the optimiser: "adam", "adamw", "rmsprop" or "sgd".

'adam'
optimizer_kwargs dict | None

Extra keyword arguments passed to the constructor of the optimiser.

None
epochs int

The number of full passes over the training data.

50
batch_size int

The size of each mini-batch.

32
show_progress bool

If True, a tqdm progress bar is shown during training.

True
random_state int | None

The seed, applied before the first training step.

42

Attributes:

Name Type Description
train_losses_

The average cross-entropy loss of each epoch, set by fit().

validation_losses_

The validation cross-entropy loss of each epoch, set by fit() when validation data is given.

Example
import numpy as np
from torch import nn
from eigenkit.torch.estimators import GenericClassifier
from eigenkit.torch.layers import Basic

rng = np.random.default_rng(0)
X_train, X_test = rng.normal(size=(30, 4)), rng.normal(size=(5, 4))
y_train = np.arange(30) % 3

# A plain PyTorch network, with a head for 3 classes.
net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 3))
clf = GenericClassifier(model=net, in_features=4, epochs=20)
clf.fit(X_train, y_train)
labels = clf.predict(X_test)
probs  = clf.predict_proba(X_test)

# A quantum layer with a classification head.
q = Basic(n_qubits=4, depth=2)
hybrid = nn.Sequential(q, nn.Linear(4, 3))
clf2 = GenericClassifier(model=hybrid, in_features=4)

accepts_sequence_input property

Whether the model expects a 3-D input (batch, seq_len, features).

fit(X, y, X_val=None, y_val=None)

Fit the model on training data.

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, in_features) for flat models, or (n_samples, seq_len, in_features) when sequence_input=True.

required
y ndarray

The class labels, of shape (n_samples,).

required
X_val ndarray | None

Optional validation samples, used to compute the validation loss of each epoch.

None
y_val ndarray | None

Optional validation labels, used to compute the validation loss of each epoch.

None

Returns:

Type Description
'GenericClassifier'

This estimator, so that calls can be chained.

Raises:

Type Description
ValueError

If X.shape[-1] or X_val.shape[-1] differs from in_features, if n_classes differs from the number of distinct labels, or if the model does not give one logit for each class.

load(path, *, model=None, provider=None) classmethod

Load a fitted GenericClassifier from a .eigenkit bundle.

The architecture of the model cannot be rebuilt automatically, so you must give it. The saved weights and the label encoder are restored automatically.

Parameters:

Name Type Description Default
path str | Path

The path of the .eigenkit bundle.

required
model Module | None

An nn.Module with the same architecture as the one used in training. Its weights are not changed: the saved weights go into a deep copy, which is model_ of the loaded estimator.

None
provider ProviderSpec | None

It is ignored. It is kept so that the signature matches the other estimators.

None

Returns:

Type Description
'GenericClassifier'

The loaded estimator.

Raises:

Type Description
SerializationError

If model is not given.

TypeError

If the bundle holds a different class.

Example
from torch import nn
from eigenkit.torch.estimators import GenericClassifier

net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 3))
clf = GenericClassifier.load("checkpoint.eigenkit", model=net)

predict(X)

Predict the class labels of X.

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, n_features).

required

Returns:

Type Description
ndarray

One prediction for each sample.

predict_proba(X)

Predict the probability of each class, with a softmax over the logits.

It returns a float32 array of shape (n_samples, n_classes).

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, n_features).

required

Returns:

Type Description
ndarray

The probabilities, of shape (n_samples, n_classes), with the columns in the order of classes_.

save(path)

Save a fitted model to a .eigenkit bundle.

The bundles of models that hold scikit-learn objects (QSVC, QSVR, the reservoir estimators and the time-series estimators) contain joblib pickles, so loading one can run code. Share them only with people who trust you.

Parameters:

Name Type Description Default
path str | Path

The path of the bundle. The suffix .eigenkit is added when it is missing.

required