PyDFLT¶
- class DFLDataset(data_dict: dict[str, ndarray | Tensor])¶
DFLDataset class extends PyTorch’s Dataset for decision-focused learning (DFL) scenarios.
It manages a dictionary of data (data_dict) where keys represent different quantities (e.g., ‘features’, ‘costs’, ‘weights’, ‘optimal_decision’) and values are torch.Tensors. The class ensures that all data tensors have the same number of samples (first dimension) and are at least 2D. It provides methods to access data by index and to add new data.
- data_dict¶
The core dictionary holding all dataset components. Keys are strings identifying the data type (e.g., ‘features’, ‘costs’), and values are torch.Tensors. All tensors are guaranteed to have the same number of samples in their first dimension and are at least 2D.
- num_samples¶
The number of samples in the dataset, determined from the first dimension of the tensors in data_dict.
- Type:
Methods
add_data(key, data)Adds new data component(s) to the dataset.
-
class Logger(experiment_name: str, project_name: str, config: dict[str, Any] | None =
None, use_wandb: bool =True, experiments_folder: str ='results/', main_metric: str ='abs_regret', store_min_and_max: bool =True)¶ A comprehensive logging class for machine learning experiments, integrating with Weights & Biases and managing local log files. It aggregates per-batch results into epoch-level metrics. See src.utils for method load_log for loading logs.
- path_to_log¶
The Path object pointing to the directory where logs are stored.
- Type:
Path
- log_file_path¶
The Path object pointing to the text log file.
- Type:
Path
- epoch_metrics_list¶
A list storing dictionaries of aggregated metrics for each epoch.
- main_metric¶
The name of the main metric used for returning values from log_epoch_results.
- Type:
Methods
finish()Finishes the Weights & Biases run if it was initialized.
log_epoch_results(per_batch_results, epoch_num)Receives a list of dictionaries with per-batch results, aggregates them, and logs.
printout()Utility function that prints out the aggregated epoch results to the console.
-
class Noisifier(base_predictor: Predictor, bias: bool =
True, sigma_setting: str ='independent', sigma_init: float | ndarray =1, sigma_final: float =0.1, total_steps_cooling: int =100, cooling_type: str ='linear', log_normal: bool =False)¶ A class that adds noise to the output of a base predictor.
The Noisifier can operate in several modes for determining the standard deviation (sigma) of the noise: - “fixed”: Sigma is a fixed value. - “cooling”: Sigma anneals from an initial to a final value over a set number of steps. - “dependent”: Sigma is predicted by a linear layer based on the input. - “independent”: Sigma is a learnable parameter, independent of the input.
It can model the output as a Normal or LogNormal distribution. If the base_predictor is an MLPNormalPredictor, it can model both the mean and standard deviation of the underlying Normal distribution with noise.
Methods
add_module(name, module)Add a child module to the current module.
apply(fn)Apply
fnrecursively to every submodule (as returned by.children()) as well as self.bfloat16()Casts all floating point parameters and buffers to
bfloat16datatype.buffers([recurse])Return an iterator over module buffers.
children()Return an iterator over immediate children modules.
compile(*args, **kwargs)Compile this Module's forward using
torch.compile().cpu()Move all model parameters and buffers to the CPU.
cuda([device])Move all model parameters and buffers to the GPU.
double()Casts all floating point parameters and buffers to
doubledatatype.eval()Set the module in evaluation mode.
extra_repr()Return the extra representation of the module.
float()Casts all floating point parameters and buffers to
floatdatatype.forward(x)Performs a forward pass, returning the mean prediction from the base predictor.
forward_dist(x[, eps])Performs a forward pass and returns a distribution object representing the noisy output.
get_buffer(target)Return the buffer given by
targetif it exists, otherwise throw an error.get_extra_state()Return any extra state to include in the module's state_dict.
get_parameter(target)Return the parameter given by
targetif it exists, otherwise throw an error.get_sigma(x)Calculates and returns the current sigma based on the setting.
get_submodule(target)Return the submodule given by
targetif it exists, otherwise throw an error.half()Casts all floating point parameters and buffers to
halfdatatype.ipu([device])Move all model parameters and buffers to the IPU.
load_state_dict(state_dict[, strict, assign])Copy parameters and buffers from
state_dictinto this module and its descendants.modules()Return an iterator over all modules in the network.
mtia([device])Move all model parameters and buffers to the MTIA.
named_buffers([prefix, recurse, ...])Return an iterator over module buffers, yielding both the name of the buffer as well as the buffer itself.
named_children()Return an iterator over immediate children modules, yielding both the name of the module as well as the module itself.
named_modules([memo, prefix, remove_duplicate])Return an iterator over all modules in the network, yielding both the name of the module as well as the module itself.
named_parameters([prefix, recurse, ...])Return an iterator over module parameters, yielding both the name of the parameter as well as the parameter itself.
output_to_dist(output)Converts the direct output of the Noisifier (which is the mean prediction) into a distribution, primarily for compatibility with interfaces expecting a distribution from the base predictor's output format.
parameters([recurse])Return an iterator over module parameters.
register_backward_hook(hook)Register a backward hook on the module.
register_buffer(name, tensor[, persistent])Add a buffer to the module.
register_forward_hook(hook, *[, prepend, ...])Register a forward hook on the module.
register_forward_pre_hook(hook, *[, ...])Register a forward pre-hook on the module.
register_full_backward_hook(hook[, prepend])Register a backward hook on the module.
register_full_backward_pre_hook(hook[, prepend])Register a backward pre-hook on the module.
register_load_state_dict_post_hook(hook)Register a post-hook to be run after module's
load_state_dict()is called.register_load_state_dict_pre_hook(hook)Register a pre-hook to be run before module's
load_state_dict()is called.register_module(name, module)Alias for
add_module().register_parameter(name, param)Add a parameter to the module.
register_state_dict_post_hook(hook)Register a post-hook for the
state_dict()method.register_state_dict_pre_hook(hook)Register a pre-hook for the
state_dict()method.requires_grad_([requires_grad])Change if autograd should record operations on parameters in this module.
set_extra_state(state)Set extra state contained in the loaded state_dict.
set_submodule(target, module[, strict])Set the submodule given by
targetif it exists, otherwise throw an error.share_memory()See
torch.Tensor.share_memory_().state_dict(*args[, destination, prefix, ...])Return a dictionary containing references to the whole state of the module.
to(device)Moves and/or casts the parameters and buffers.
to_empty(*, device[, recurse])Move the parameters and buffers to the specified device without copying storage.
train([mode])Set the module in training mode.
type(dst_type)Casts all parameters and buffers to
dst_type.update_t(new_t)Updates the current step t for sigma cooling.
xpu([device])Move all model parameters and buffers to the XPU.
zero_grad([set_to_none])Reset gradients of all model parameters.
__call__
-
class Problem(data_dict: dict[str, ndarray], opt_model: OptimizationModel, train_ratio: float =
0.7, val_ratio: float =0.15, compute_optimal_decisions: bool =True, compute_optimal_objectives: bool =True, standardize_features: bool =False, time_respecting_split: bool =False, knn_robust_loss: int =0, knn_robust_loss_weight: float =0.0, seed: int | None =None, verbose: bool =True)¶ Manages a decision-focused learning (DFL) problem encapsulating the dataset (DFLDataset) and an optimization model (OptimizationModel). It is responsible for:
Splitting the data into training, validation, and test sets.
Standardizing features if specified.
Computing optimal decisions and objectives for the dataset instances, potentially using a k-NN robust approach if configured.
Providing an interface to access data batches for different modes (train/val/test).
Delegating solving, objective calculation, and evaluation tasks to the OptimizationModel.
- mode¶
The current operational mode of the problem instance (e.g., ‘train’, ‘validation’, ‘test’).
- Type:
Optional[str]
- train_indices¶
Indices for the training dataset.
- Type:
Optional[np.ndarray]
- validation_indices¶
Indices for the validation dataset.
- Type:
Optional[np.ndarray]
- test_indices¶
Indices for the test dataset.
- Type:
Optional[np.ndarray]
- opt_model¶
The optimization model associated with the problem.
- Type:
OptimizationModel
- params_to_predict_shapes¶
Shapes of the parameters to be predicted by a machine learning model, as defined in opt_model.
- Type:
Dict[str, Tuple]
- num_predictions¶
Total number of scalar values to be predicted, derived from params_to_predict_shapes.
- Type:
- dataset¶
The dataset object holding all problem instances.
- Type:
- compute_optimal_decisions¶
If True, computes and stores the optimal decisions for each instance in the dataset. Defaults to True.
- Type:
bool, optional
- time_respecting_split¶
Whether to perform a time-respecting split (no shuffling before splitting).
- Type:
- knn_robust_loss¶
If greater than 0, enables k-NN robust loss computation for the training set, using this value as the number of neighbours ‘k’. This involves finding k-nearest neighbors to perturb parameters for robust decision-making. Defaults to 0 (disabled).
- Type:
int, optional
- mode_to_indices¶
A dictionary mapping mode strings (‘train’, ‘validation’, ‘test’) to their corresponding data indices.
- all_indices¶
An array of all indices from 0 to num_samples-1.
- Type:
np.ndarray
Attributes
mode
test_indices
train_indices
validation_indices
Methods
evaluate(data_batch, decisions_batch[, ...])Evaluates various performance metrics for a batch, given true data, decisions, and optionally, predicted parameters.
generate_batch_indices(batch_size)Generates a list of index arrays (batches) for the currently set mode.
get_objective(data_batch, decisions_batch[, ...])Calculates the objective value for a batch, given the true data, decisions, and optionally, predicted parameters.
read_data(idx)Retrieves data from the dataset for the specified indices.
set_mode(mode)Sets the current operational mode of the Problem instance.
solve(data_batch)Solves the optimization problem for a given batch of data.
split_dataset([seed])Splits the dataset indices into training, validation, and test sets.
-
class Runner(decision_maker: DecisionMaker, num_epochs: int =
3, experiments_folder: str ='results/', main_metric: str ='abs_regret', val_metrics: list[str] | None =None, test_metrics: list[str] | None =None, store_min_and_max: bool =False, use_wandb: bool =False, experiment_name: str ='-', project_name: str ='-', early_stop: bool =False, min_delta_early_stop: float | None =None, patience_early_stop: float | None =None, save_best: bool =True, seed: int | None =None, full_reproducibility_GPUs: bool =False, config: dict[str, Any] | None =None, verbose: bool =True)¶ The Runner class allows for running experiments. It uses the given DecisionMaker to run the experiments with and initializes a Logger to log results. It handles the training and evaluation process, including logging, early stopping, and saving the best models found so far.
- decision_maker¶
The decision maker instance to be trained and evaluated.
- Type:
- min_delta_early_stop¶
Minimum change in the main metric to be considered an improvement for early stopping.
- Type:
float | None
- patience_early_stop¶
Number of epochs to wait for an improvement before stopping early.
- Type:
float | None
- no_improvement_count¶
Counter for epochs without significant improvement, used for early stopping.
- Type:
Methods
run([optuna_trial])Runs the experiment.
-
class DecisionMaker(problem: Problem, learning_rate: float =
1e-4, device_str: str ='cpu', predictor_str: str ='MLP', decision_model_str: str ='base', loss_function_str: str ='objective', to_decision_pars: str ='none', use_dist_at_mode: str ='none', use_noisifier: bool =False, standardize_predictions: bool =True, init_OLS: bool =False, seed: int | None =None, predictor_kwargs: dict | None =None, noisifier_kwargs: dict | None =None, decision_model_kwargs: dict | None =None)¶ Abstract base class for a decision-making agent in a decision-focused learning pipeline.
This class orchestrates the interaction between a predictive model (predictor), an optional noisifier to add stochasticity to predictions, and a decision_model (an optimization model) to make decisions based on (potentially noisy) predictions. It handles the initialization of these components, the process of predicting parameters and making decisions, and provides hooks for training and evaluation.
The class is organized into several categories of methods: - Abstract methods for subclass implementation: Need to be implemented for a subclass to work. - Core logic methods: Methods that include the core logic of what a decision maker entails - Helper methods: Local methods that support other methods - Conversion methods: Methods that convert, i.e., transform or reshape certain objects. - Initialization methods: Methods that do initialization
- device¶
The device (CPU or GPU) on which computations are performed.
- Type:
torch.device
- to_decision_pars¶
Strategy for converting distributional predictions to deterministic parameters for the decision model (e.g., ‘sample’, ‘quantiles’).
- Type:
- use_dist_at_mode¶
Specifies if/when to use full distributional output from predictor/noisifier (e.g., ‘test’ mode).
- Type:
- decision_model¶
The instantiated optimization model used for making decisions.
- Type:
OptimizationModel
- best_predictor¶
A copy of the predictor with the best validation performance.
- Type:
Predictor | None
- trainable_predictive_model¶
The PyTorch module that is trained (either the predictor or the noisifier if used).
- Type:
nn.Module
- num_scenarios¶
Number of scenarios used if to_decision_pars involves sampling or quantiles, derived from decision_model_kwargs.
- Type:
int | None
- _epoch_counts¶
Counter for the number of epochs run (though not explicitly updated in this snippet).
- Type:
Attributes
best_predictor
Methods
decide(predictions_batch)Makes decisions using the self.decision_model based on the provided predictions.
dict_to_decisions(decisions_batch[, use_optimal])Reverts a dictionary of named parameter predictions back into a single flat tensor.
dict_to_predictions(predictions_batch)Reverts a dictionary of named parameter predictions back into a single flat tensor.
dict_to_tensor(predictions_dict[, output_device])Converts a dictionary of tensors to a single tensor by concatenating them.
predict(data_batch[, output_device])Generates predictions for a given data batch.
predict_and_decide(data_batch)Performs a prediction step followed by a decision-making step.
predictions_to_dict(predictions[, output_device])Converts a flat tensor of predictions into a dictionary.
run_epoch(mode, epoch_num[, metrics])Runs one full epoch of operations (training, validation, or testing).
save_best_predictor()Saves a deep copy of the current self.predictor to self.best_predictor.
update(data_batch)Performs a single training update step for the learnable components.
-
class Predictor(num_inputs: int, num_outputs: int, num_scenarios: int =
1)¶ Base class for all predictors. Predictors are restricted to be instances of torch.nn.Module.
- num_outputs¶
The total number of outputs the predictor produces. If num_scenarios > 1, this is the total output (output_per_scenario * num_scenarios).
- Type:
- num_scenarios¶
The number of scenarios the predictor is designed to handle. If 1, the predictor outputs a single prediction. If > 1, the predictor outputs multiple predictions (one per scenario).
- Type:
Methods
add_module(name, module)Add a child module to the current module.
apply(fn)Apply
fnrecursively to every submodule (as returned by.children()) as well as self.bfloat16()Casts all floating point parameters and buffers to
bfloat16datatype.buffers([recurse])Return an iterator over module buffers.
children()Return an iterator over immediate children modules.
compile(*args, **kwargs)Compile this Module's forward using
torch.compile().cpu()Move all model parameters and buffers to the CPU.
cuda([device])Move all model parameters and buffers to the GPU.
double()Casts all floating point parameters and buffers to
doubledatatype.eval()Set the module in evaluation mode.
extra_repr()Return the extra representation of the module.
float()Casts all floating point parameters and buffers to
floatdatatype.forward(x)Abstract method for the forward pass of the predictor.
forward_mean(x)Computes the mean of the predictor's output across scenarios.
get_buffer(target)Return the buffer given by
targetif it exists, otherwise throw an error.get_extra_state()Return any extra state to include in the module's state_dict.
get_parameter(target)Return the parameter given by
targetif it exists, otherwise throw an error.get_submodule(target)Return the submodule given by
targetif it exists, otherwise throw an error.half()Casts all floating point parameters and buffers to
halfdatatype.ipu([device])Move all model parameters and buffers to the IPU.
load_state_dict(state_dict[, strict, assign])Copy parameters and buffers from
state_dictinto this module and its descendants.modules()Return an iterator over all modules in the network.
mtia([device])Move all model parameters and buffers to the MTIA.
named_buffers([prefix, recurse, ...])Return an iterator over module buffers, yielding both the name of the buffer as well as the buffer itself.
named_children()Return an iterator over immediate children modules, yielding both the name of the module as well as the module itself.
named_modules([memo, prefix, remove_duplicate])Return an iterator over all modules in the network, yielding both the name of the module as well as the module itself.
named_parameters([prefix, recurse, ...])Return an iterator over module parameters, yielding both the name of the parameter as well as the parameter itself.
parameters([recurse])Return an iterator over module parameters.
register_backward_hook(hook)Register a backward hook on the module.
register_buffer(name, tensor[, persistent])Add a buffer to the module.
register_forward_hook(hook, *[, prepend, ...])Register a forward hook on the module.
register_forward_pre_hook(hook, *[, ...])Register a forward pre-hook on the module.
register_full_backward_hook(hook[, prepend])Register a backward hook on the module.
register_full_backward_pre_hook(hook[, prepend])Register a backward pre-hook on the module.
register_load_state_dict_post_hook(hook)Register a post-hook to be run after module's
load_state_dict()is called.register_load_state_dict_pre_hook(hook)Register a pre-hook to be run before module's
load_state_dict()is called.register_module(name, module)Alias for
add_module().register_parameter(name, param)Add a parameter to the module.
register_state_dict_post_hook(hook)Register a post-hook for the
state_dict()method.register_state_dict_pre_hook(hook)Register a pre-hook for the
state_dict()method.requires_grad_([requires_grad])Change if autograd should record operations on parameters in this module.
set_extra_state(state)Set extra state contained in the loaded state_dict.
set_submodule(target, module[, strict])Set the submodule given by
targetif it exists, otherwise throw an error.share_memory()See
torch.Tensor.share_memory_().state_dict(*args[, destination, prefix, ...])Return a dictionary containing references to the whole state of the module.
to(*args, **kwargs)Move and/or cast the parameters and buffers.
to_empty(*, device[, recurse])Move the parameters and buffers to the specified device without copying storage.
train([mode])Set the module in training mode.
type(dst_type)Casts all parameters and buffers to
dst_type.xpu([device])Move all model parameters and buffers to the XPU.
zero_grad([set_to_none])Reset gradients of all model parameters.
__call__