DenseLayer#

class pyqit.models.layers.DenseLayer(n_features, n_out, activation=None)[source]#

Bases: BaseModel

Classical dense stage: activation(X @ weight.T + bias).

Emits features, not predictions, so it is a QuantumPipeline stage rather than something to fit alone. Stack several for a deeper network. Weights use torch.nn.Linear’s default init on both backends, under dense.weight and dense.bias.

Parameters:
  • n_features (int)

  • n_out (int)

  • activation ({None, "tanh", "relu", "sigmoid"}, default None)

Examples

>>> from pyqit.models.layers import DenseLayer
>>> layer = DenseLayer(n_features=8, n_out=4, activation="tanh")
execute_qnode(name: str, X, **custom_weights)#

Run the QNode or dense layer registered under name on a batch.

Parameters:
  • name (str) – Name passed to register_qnode.

  • X (array-like)

  • **custom_weights – Flat “<name>.<weight>” overrides; unprefixed keys are ignored. Falls back to the model’s own weights when empty.

Return type:

array-like

forward(X, **custom_weights)[source]#

Return (n_samples, n_out) features.

classmethod get_test_params()[source]#

List constructor kwargs used to parametrize this class in the test suite.

is_fitted() → bool#

Whether Trainer.fit has trained this model.

register_dense(name: str, n_in: int, n_out: int, weights=None)#

Register a classical dense layer X @ weight.T + bias under name.

Lives in the same registry as the QNodes, so weights, update_weights, checkpoints and the flat-kwargs routing cover it with no further plumbing. Run it with execute_qnode.

Parameters:
  • name (str)

  • n_in (int)

  • n_out (int)

  • weights (dict, optional) – {"weight", "bias"} from init_dense_weights; drawn when omitted.

update_weights(flat_weights_dict)#

Write flat_weights_dict into the model’s own weights.

No-op under torch, where autograd owns the nn.Parameter objects directly.

Parameters:

flat_weights_dict (dict) – Keyed like weights.

weight_groups() → dict#

weights keys by group, "quantum" (QNodes) and "classical".

Empty groups are omitted. The training loops build one optimizer per group, which is what lets Trainer(learning_rate={...}) set a rate per group.

property weights#

Flat {"<qnode_name>.<weight_name>": array} dict, both backends.