Core Model#
model
#
| CLASS | DESCRIPTION |
|---|---|
Model |
Base model class for neural networks with post-training transformations. |
Classes#
Model(in_features: int | None = None, out_features: int | None = None, multipliers: list[float] | None = None, layers: OrderedDict | torch.nn.Sequential | None = None, activation_fn: Callable = torch.nn.ELU, output_fn: torch.nn.Module | None = None, dropout_prob: float = 0.0, batch_norm: bool = False, orthogonal_weights: bool = False)
#
Bases: Module, ABC
Base model class for neural networks with post-training transformations.
Creates customizable neural networks with optional batch normalization, dropout, and orthogonal weight parametrization. Supports both layer-based and parameter-based construction with post-training transformation capabilities. Supports JIT compilation.
Unlike Estimator for non-parametric methods, which follows
the scikit-learn pattern of fit, predict,
and score, Model is a PyTorch torch.nn.Module subclass and follows
the PyTorch pattern of defining a forward method. This makes
Model suitable for parametric methods such as neural networks.
Model can be used to define simple feedforward networks with its parameters
such as in_features, out_features, and multipliers. For more complex
architectures, pre-constructed layers can be passed via the
layers parameter. Additionally, Model supports adding post-training
transformations through the add_transform() method, which can be used
to apply operations like normalization or dimensionality reduction after
the main network.
| PARAMETER | DESCRIPTION |
|---|---|
in_features
|
Number of input features. Required when layers is None.
TYPE:
|
out_features
|
Number of output features. Required when layers is None.
TYPE:
|
multipliers
|
Layer width multipliers for automatic construction.
TYPE:
|
layers
|
Pre-constructed layers to use instead of automatic construction.
TYPE:
|
activation_fn
|
Activation function class for hidden layers.
TYPE:
|
output_fn
|
Final output activation function, if None no output activation is applied.
TYPE:
|
dropout_prob
|
Dropout probability in range [0, 1). Zero disables dropout.
TYPE:
|
batch_norm
|
Whether to use batch normalization after linear layers.
TYPE:
|
orthogonal_weights
|
Whether to use orthogonal weight parametrization.
TYPE:
|
| ATTRIBUTE | DESCRIPTION |
|---|---|
in_features |
Number of input features.
TYPE:
|
out_features |
Number of output features.
TYPE:
|
Examples:
Creating a simple feedforward network with specified layer widths:
>>> import torch
>>> from spectre.core import Model
>>> model = Model(
... in_features=10,
... out_features=2,
... multipliers=[0.8, 0.5],
... activation_fn=torch.nn.ReLU,
... )
>>> print(model)
Model(
(sequential): Sequential(
(layer_0): Linear(in_features=10, out_features=8, bias=True)
(act_0): ReLU()
(layer_1): Linear(in_features=8, out_features=5, bias=True)
(act_1): ReLU()
(layer_2): Linear(in_features=5, out_features=2, bias=True)
)
>>> X = torch.randn(5, 10) # Example input
>>> output = model(X)
>>> print(output.shape)
torch.Size([5, 2])
Creating a model from pre-constructed layers:
>>> layers = torch.nn.Sequential(
... torch.nn.Linear(10, 20),
... torch.nn.ReLU(),
... torch.nn.Linear(20, 5),
... torch.nn.ReLU(),
... torch.nn.Linear(5, 2),
... )
>>> model = Model(layers=layers)
>>> print(model)
Model(
(sequential): Sequential(
(0): Linear(in_features=10, out_features=20, bias=True)
(1): ReLU()
(2): Linear(in_features=20, out_features=5, bias=True)
(3): ReLU()
(4): Linear(in_features=5, out_features=2, bias=True)
)
)
>>> X = torch.randn(5, 10) # Example input
>>> output = model(X)
>>> print(output.shape)
torch.Size([5, 2])
Adding a post-training transformation:
>>> from spectre.transform import L2Normalizer
>>> model.add_transform(L2Normalizer(), name="normalize")
>>> print(model.get_transforms())
[{'name': 'normalize', 'type': 'Transformer'}]
>>> output = model(X) # Forward pass with transformation applied
>>> print(output.shape)
torch.Size([5, 2])
Notes
- When using
layers,in_featuresandout_featuresare inferred from the first and last layers respectively. - Post-training transformations are applied in the order they were added.
- Transformations can be Transformer instances or any
torch.nn.Module. - Supports JIT compilation via
torch.jit.scriptortorch.jit.trace.
| METHOD | DESCRIPTION |
|---|---|
forward |
Forward pass with optional post-training transformations. |
add_transform |
Add post-training transformation to the model. |
clear_transforms |
Clear all post-training transformations. |
get_transforms |
Get information about registered transformations. |
freeze_layers |
Freeze layers to prevent gradient updates. |
unfreeze_layers |
Unfreeze layers to enable gradient updates. |
get_frozen_layers |
Get names of frozen layers. |
layer_shapes |
Get input/output shapes for each layer. |
count_parameters |
Count total parameters in model. |
summary |
Get model summary string. |
compress |
Create a compressed version of the model by reducing layer sizes. |
Source code in spectre/core/model.py
Attributes#
in_features: int
property
writable
#
Number of input features.
out_features: int
property
writable
#
Number of output features.
is_trained: bool
property
writable
#
Whether the model has been trained.
Functions#
forward(X: torch.Tensor) -> torch.Tensor
#
Forward pass with optional post-training transformations.
| PARAMETER | DESCRIPTION |
|---|---|
X
|
Input tensor of shape (n_samples, in_features).
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Tensor
|
Output tensor of shape (n_samples, out_features). |
Source code in spectre/core/model.py
add_transform(transform: Transformer | torch.nn.Module, name: str | None = None) -> None
#
Add post-training transformation to the model.
Transformations are applied after the main network in the order they
were added. Supports both Transformer instances
(with transform() and inverse_transform() methods) and standard
torch.nn.Module instances.
| PARAMETER | DESCRIPTION |
|---|---|
transform
|
Transformation to add. Can be a
TYPE:
|
name
|
Transform name. Auto-generated if None.
TYPE:
|
Examples:
>>> from spectre.transform import ProjectionTransformer, L2Normalizer
>>> model = Model(in_features=10, out_features=5)
>>> # Add projection transformer
>>> proj = ProjectionTransformer(torch.randn(3, 5))
>>> model.add_transform(proj, "projection")
>>> # Add normalization
>>> model.add_transform(L2Normalizer(), "normalize")
Source code in spectre/core/model.py
clear_transforms() -> None
#
get_transforms() -> list[dict[str, str]]
#
Get information about registered transformations.
| RETURNS | DESCRIPTION |
|---|---|
list[dict[str, str]]
|
List of dicts with "name" and "type" keys for each transform. |
Source code in spectre/core/model.py
freeze_layers(layer_names: list[str] | None = None, freeze_all: bool = False) -> None
#
Freeze layers to prevent gradient updates.
| PARAMETER | DESCRIPTION |
|---|---|
layer_names
|
Names of layers to freeze. If None, uses freeze_all.
TYPE:
|
freeze_all
|
If True, freeze all layers.
TYPE:
|
Examples:
>>> model = Model(in_features=100, out_features=10, multipliers=[0.5])
>>> model.freeze_layers(["layer_0"]) # Freeze first layer
>>> model.freeze_layers(freeze_all=True) # Freeze all
Source code in spectre/core/model.py
unfreeze_layers(layer_names: list[str] | None = None, unfreeze_all: bool = False) -> None
#
Unfreeze layers to enable gradient updates.
| PARAMETER | DESCRIPTION |
|---|---|
layer_names
|
Names of layers to unfreeze. If None, uses unfreeze_all.
TYPE:
|
unfreeze_all
|
If True, unfreeze all layers.
TYPE:
|
Source code in spectre/core/model.py
get_frozen_layers() -> list[str]
#
Get names of frozen layers.
| RETURNS | DESCRIPTION |
|---|---|
list[str]
|
Names of layers with all parameters frozen. |
Source code in spectre/core/model.py
layer_shapes() -> dict[str, tuple]
#
Get input/output shapes for each layer.
| RETURNS | DESCRIPTION |
|---|---|
dict[str, tuple]
|
Mapping from layer name to (in_shape, out_shape). |
Examples:
>>> model = Model(in_features=100, out_features=10, multipliers=[0.5])
>>> model.layer_shapes()
{'layer_0': (100, 50), 'layer_1': (50, 10)}
Source code in spectre/core/model.py
count_parameters(trainable_only: bool = False) -> int
#
Count total parameters in model.
| PARAMETER | DESCRIPTION |
|---|---|
trainable_only
|
If True, only count trainable parameters.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
int
|
Number of parameters. |
Source code in spectre/core/model.py
summary() -> str
#
Get model summary string.
| RETURNS | DESCRIPTION |
|---|---|
str
|
Formatted summary with layer info and parameter counts. |
Source code in spectre/core/model.py
compress(ratio: float, preserve_io: bool = True) -> Model
#
Create a compressed version of the model by reducing layer sizes.
Creates a new model with reduced hidden layer dimensions while optionally preserving input and output dimensions. Only works with sequential models containing at least two linear layers.
| PARAMETER | DESCRIPTION |
|---|---|
ratio
|
Compression ratio between 0 and 1. For example,
TYPE:
|
preserve_io
|
Whether to preserve input and output dimensions. If True, only compresses hidden layers. If False, compresses all layers except the final output layer.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Model
|
New compressed model with reduced layer sizes. |
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If ratio is not a float. |
ValueError
|
If ratio is not in the range (0, 1). |
Examples:
>>> model = Model(in_features=100, out_features=10, multipliers=[2.0, 1.5])
>>> print(model.layer_shapes())
{'layer_0': (100, 200), 'layer_1': (200, 150), 'layer_2': (150, 10)}
>>> compressed = model.compress(ratio=0.5, preserve_io=True)
>>> print(compressed.layer_shapes())
{'layer_0': (100, 100), 'layer_1': (100, 75), 'layer_2': (75, 10)}
Compress all layers except output:
>>> compressed = model.compress(ratio=0.5, preserve_io=False)
>>> print(compressed.layer_shapes())
{'layer_0': (50, 100), 'layer_1': (100, 75), 'layer_2': (75, 10)}
Notes
- The original model is not modified; a new model is created
- Weights are randomly initialized (not copied from the original)
- Only compresses models with
torch.nn.Linearlayers - Non-linear layers (activations, dropout, batch norm) are preserved
- If the model has fewer than two linear layers, returns a copy
Source code in spectre/core/model.py
620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 | |