Learning and Training¶
Structure and parameter learning algorithms for probabilistic circuits.
Structure Learning¶
Automatic structure learning using the LearnSPN algorithm based on Randomized Dependence Coefficients (RDC).
- spflow.learn.learn_spn.learn_spn(data, leaf_modules, out_channels=1, min_features_slice=2, min_instances_slice=100, scope=None, clustering_method='kmeans', partitioning_method='rdc', clustering_args=None, partitioning_args=None, full_data=None)[source]¶
LearnSPN structure and parameter learner.
LearnSPN algorithm as described in (Gens & Domingos, 2013): “Learning the Structure of Sum-Product Networks”.
- Parameters:
data (
Tensor) – Two-dimensional Tensor containing the input data. Each row corresponds to a sample.leaf_modules (
list[LeafModule] |LeafModule) – List of leaf modules or single leaf module to use for learning.out_channels (
int) – Number of output channels. Defaults to 1.min_features_slice (
int) – Minimum number of features required to partition. Defaults to 2.min_instances_slice (
int) – Minimum number of instances required to cluster. Defaults to 100.scope – Scope for the SPN. If None, inferred from leaf_modules.
clustering_method (
str|Callable) – String or callable specifying the clustering method. If ‘kmeans’, k-Means clustering is used. If a callable, it should accept data and return cluster assignments.partitioning_method (
str|Callable) – String or callable specifying the partitioning method. If ‘rdc’, randomized dependence coefficients are used. If a callable, it should accept data and return partition assignments.clustering_args (
dict[str,Any] |None) – Optional dictionary of keyword arguments for clustering method.partitioning_args (
dict[str,Any] |None) – Optional dictionary of keyword arguments for partitioning method.full_data (
Tensor|None) – Optional full dataset for parameter estimation.
- Return type:
Module- Returns:
A Module representing the learned SPN.
- Raises:
ValueError – If arguments are invalid or scopes are not disjoint.
Automatic structure learning using the Prometheus algorithm for learning DAG-structured SPNs (with optional subtree sharing).
- spflow.learn.prometheus.learn_prometheus(data, leaf_modules, out_channels=1, min_features_slice=2, min_instances_slice=100, scope=None, n_clusters=2, clustering_method='kmeans', similarity='corr', affinity_mode='full', sampling_per_var=None, sampling_seed=None, clustering_args=None, similarity_args=None)[source]¶
Learn an SPN structure using Prometheus.
- Parameters:
data (
Tensor) – 2D tensor (batch, num_total_features) containing training data.leaf_modules (
list[LeafModule] |LeafModule) – Leaf module template(s) to use for fitting univariate/multivariate leaves.out_channels (
int) – Number of independent learned circuits (concatenated along channels).min_features_slice (
int) – Stop recursion when scope smaller than this.min_instances_slice (
int) – Stop recursion when fewer than this many samples at a node.scope (
Scope|None) – Scope to learn over. If None, inferred from leaf_modules.n_clusters (
int) – Number of instance clusters per recursion node (default 2).clustering_method (
str|Callable[...,Tensor]) – “kmeans” or a callable. Callable must accept (scoped_data, n_clusters=…).similarity (
str|Callable[[Tensor],Tensor]) – “corr”, “rdc”, or a callable mapping (scoped_cluster_data) -> affinity(d,d).affinity_mode (
str) – “full” (default) or “sampled” for the scalable approximation. Sampled mode supports only “corr” or “rdc” similarities.sampling_per_var (
int|None) – Number of sampled neighbors per variable when affinity_mode=”sampled”. Defaults to max(1, min(d-1, floor(log2(d)))) for each recursion scope.sampling_seed (
int|None) – Optional seed for deterministic neighbor sampling.clustering_args (
dict[str,Any] |None) – Optional kwargs bound to clustering_method.similarity_args (
dict[str,Any] |None) – Optional kwargs bound to similarity method.
- Return type:
Module- Returns:
Learned SPN as a Module (may be a DAG with subtree sharing).
- Raises:
InvalidTypeError – If arguments have invalid types.
InvalidParameterError – If argument values are invalid or inconsistent.
UnsupportedOperationError – If data contains NaNs (not supported for affinity computation).
Pseudocode (Prometheus, from Jaini et al. 2018):
Prometheus(D, X): if |X| == 1: return univariate leaf fit on D cluster D into {D_i}; create sum node N for each D_i: build affinity matrix M_i and MST T_i while T_i has edges: remove weakest edge from T_i create product node P over connected components add all products from D_i as children of N for each product node P under N: for each scope S in P: if sub-SPN for S not built: build S via Prometheus(D restricted to S, S) attach S as child of P return N
Parameter Learning: EM¶
Expectation-Maximization algorithm for parameter optimization.
- spflow.learn.expectation_maximization.expectation_maximization(module, data, max_steps=-1, bias_correction=True, verbose=False)[source]¶
Performs expectation-maximization optimization on a given module.
- Parameters:
module (
Module) – Module to perform EM optimization on.data (
Tensor) – Two-dimensional tensor containing the input data. Each row corresponds to a sample.max_steps (
int) – Maximum number of iterations. Defaults to -1, in which case optimization runs until convergence.bias_correction (
bool) – Whether to apply bias correction in leaf MLE updates. Defaults to True.verbose (
bool) – Whether to print the log-likelihood for each iteration step. Defaults to False.
- Return type:
- Returns:
One-dimensional tensor containing the average log-likelihood for each iteration step.
Parameter Learning: Gradient Descent¶
Gradient descent-based parameter learning using PyTorch optimizers.
- spflow.learn.gradient_descent.train_gradient_descent(model, dataloader, epochs=-1, verbose=False, is_classification=False, optimizer=None, scheduler=None, lr=0.001, loss_fn=None, validation_dataloader=None, callback_batch=None, callback_epoch=None, nll_weight=1.0)[source]¶
Train model using gradient descent.
- Parameters:
model (
Module) – Model to train, must inherit from Module.dataloader (
DataLoader) – Training data loader yielding batches.epochs (
int) – Number of training epochs. Must be positive.verbose (
bool) – Whether to log training progress per epoch.is_classification (
bool) – Whether this is a classification task.optimizer (
Optimizer|None) – Optimizer instance. Defaults to Adam if None.scheduler (
LRScheduler|None) – Learning rate scheduler. Defaults to MultiStepLR if None.lr (
float) – Learning rate for default Adam optimizer.loss_fn (
Callable[[Module,Tensor],Tensor] |None) – Custom loss function. Defaults based on task type if None.validation_dataloader (
DataLoader|None) – Validation data loader for periodic evaluation.callback_batch (
Callable[[Tensor,int],None] |None) – Function called after each batch with (loss, step).callback_epoch (
Callable[[list[Tensor],int],None] |None) – Function called after each epoch with (losses, epoch).nll_weight (
float) – Weight for the density estimation (NLL) term when is_classification=True. Controls the balance between discriminative and generative loss. Default is 1.0.
- Raises:
ValueError – If epochs is not a positive integer.
InvalidTypeError – If is_classification is True and model is not a Classifier instance.
SOCS Builder¶
Build a SOCS model from a compatible template circuit.
- spflow.learn.build_socs.build_socs(template, *, num_components, signed=True, noise_scale=0.05, flip_prob=0.5, seed=None)[source]¶
Build a SOCS model from a compatible component template.
- Parameters:
template (
Module) – A SPFlow module representing a (typically scalar-output) circuit. This circuit is deep-copied num_components times to ensure all components share the same structure.num_components (
int) – Number of components r.signed (
bool) – If True, convert all Sum nodes in each clone to SignedSum nodes with perturbed weights (allowing negative weights).noise_scale (
float) – Standard deviation of additive Gaussian noise applied to copied weights when signed=True.flip_prob (
float) – Probability of flipping the sign of each weight entry when signed=True. Must be in [0, 1].seed (
int|None) – Optional random seed used for weight perturbations.
- Return type:
- Returns:
A SOCS module with num_components compatible components.