All the links provided with this repository are for cited/anonymous GitHub repositories and websites
We introduce Learning to Condition (L2C), a scalable, data-driven framework for accelerating Most Probable Explanation (MPE) inference in Probabilistic Graphical Models (PGMs)—a fundamentally intractable problem. L2C trains a neural network to score variable-value assignments based on their utility for conditioning, given observed evidence. To facilitate supervised learning, we develop a scalable data generation pipeline that extracts training signals from the search traces of existing MPE solvers. The trained network serves as a heuristic that integrates with search algorithms, acting as a conditioning strategy prior to exact inference or as a branching and node selection policy within branch-and-bound solvers. We evaluate L2C on challenging MPE queries involving high-treewidth PGMs. Experiments show that our learned heuristic significantly reduces the search space while maintaining or improving solution quality over state-of-the-art methods.
- Learning to Condition
.
└── MPE
├── dataset
│ ├── .gitkeep
├── data_collection
│ ├── branching_rules.py
│ ├── generate_dataset_depth.py
│ └── generate_dataset.py
├── evaluation
│ ├── base.py
│ ├── evaluate.py
│ ├── evaluation_results.py
│ └── scip_extensions.py
├── train
│ ├── data_utils.py
│ ├── loss_functions.py
│ ├── metrics.py
│ ├── models.py
│ └── train.py
└── utils
├── pytorch_utils.py
└── utils.py
- Benchmark UAI models have been taken from link.
- All the model UAI files will be saved under the
datasetdirectory under theMPEdirectory. See directory structure - For a given PGM model, download the UAI model and save the file to under
datasetwith the filenamepgm-model.uai
<NETWORK_NAME>
├── [-rw-r--r--] pgm-model.uai
We used the following packages with their versions
- Python 3.8
- Pyscipopt 5.2
- Pytorch 2.4 with CUDA 12.1
- Numpy 1.24
- Pandas 2.0
- Hardware: Intel Xeon Silver with NVIDIA A40 GPU
- Create a Virtual Environment:
python -m venv venv source venv/bin/activate - Install Dependencies:
pip install -r requirements.txt
This section details the steps to collect the L2C dataset. As an example, we will execute all our experiments for the BN_9 network. This section outlines the process for acquiring and preparing the data for this project.
Declare the NETWORK_NAME environment variable in the terminal
NETWORK_NAME=BN_9Assuming you followed the directory structure from section 3.1, generate the samples for the declared network using following command.
SAMPLE_SIZE=<Choose number of samples>
python -m MPE.utils.utils --network-name $NETWORK_NAME --test-type samples --sample-size $SAMPLE_SIZE- This will save unique samples to the
MPE/dataset/$NETWORK_NAME/train.txt. - Manually split the
train.txtfile into train and test files by copying required number of samples fromtrain.txttotest.txtand then removing the copied samples fromtrain.txt - You should have train.txt and test.txt under the
$NETWORK_NAMEdirectory<NETWORK_NAME> ├── [-rw-r--r--] pgm-model.uai ├── [-rw-r--r--] test.txt ├── [-rw-r--r--] train.txt
- We used the 13000 samples as the size of our training set. Please choose an appropriate size for your experiments
- Do not choose a size larger than the number of samples created in the previous step
- To create the training dataset for our network, run the command
DATASET_SIZE=<Choose a dataset size>
NUM_WORKERS=4 # For parallel execution
python -m MPE.data_collection.generate_dataset_depth --network-name $NETWORK_NAME --num-samples $DATASET_SIZE --num-workers $NUM_WORKERSNow, we are ready to train the L2C models.
-
Config We have defined the config in the training script with the following values
- Training samples: 12000
- Validation samples: 1000
- Adam Optimizer with Learning Rate : 8e-4
- Exponential Decay on learning rate: 0.97
- Epoch Size: 50
- Batch Size: 128
-
Model Architecture
- Dataset is read in a DataLoader defined in data_utils.py
- Model architecture is defined in models.py
- Embedding layers size is initialized at 256
- Hidden layers size is initialized at 512
- Loss Functions
- Loss functions are defined in loss_funtions.py
- Optimality head is trained using the
BBListMLClassficationLossFunctionLoss - Simplification head is trained using the
BBListRankingLossFunctionV2Loss
- Validation Metrics
- Validation Metrics are defined in metrics.py
- Execute the training script:
python -m MPE.train.train --network-name $NETWORK_NAME - Monitoring Progress
- Current loss is printed to the console every 10 batches
- After every epoch the loss for both the heads are printed to console
- Loss(epoch.log) and validation metrics(result.log) are saved in separate log files saved at
MPE/dataset/$NETWORK_NAME/training-artifacts/l2c/logs - Model checkpoints will be saved at
MPE/dataset/$NETWORK_NAME/training-artifacts/l2c/trained-models
Evaluation will be executed on the previously created test.txt in section 4.2.
- We recommend initializing the following set of variables to facilitate smooth execution of the experiments.
- DEPTH - Used to define the conditioning depth percentage of query variables. Use integer values.
- WIDTH - Integer value used to define the beam width for the beam search strategy. Use 1 for greedy conditioning
- RUNNER & METHOD - Strategy to be used for conditioning
- Valid values for respective methods used in the paper
- For L2C-Opt for conditioning, define
RUNNER=neural METHOD=l2c_opt
- For L2C-Opt for conditioning, define
RUNNER=neural METHOD=l2c_rank
- For L2C-Opt as SCIP search heuristics, define
RUNNER=neural_search METHOD=l2c_opt
- For L2C-Rank as SCIP search heuristics, define
RUNNER=neural_search METHOD=l2c_opt
- For graph based heuristic for conditioning, define
RUNNER=graph METHOD=graph
- For full strong branching for conditioning, define
RUNNER=strong_branch METHOD=strong_branch
- For L2C-Opt for conditioning, define
-
To run the evalution using
L2C-rank, please execute the following blockDEPTH=5 WIDTH=1 # Use values 3 and 5 for different beam widths RUNNER=neural METHOD=l2c_rank NUM_WORKERS=4 # For parallel execution of queries python -m MPE.evaluation.evaluate --network-name $NETWORK_NAME --num-cases 1000 --num-workers $NUM_WORKERS --qr 0.75 --out-file results.json --runner $RUNNER --config-name $METHOD --depth $DEPTH --beam-width $WIDTH
- First install DAOOPT from here and save the binary with file name
daooptin the project folder. - Execute the steps from section 6.1.1
- Execute the following steps
DEPTH=5 WIDTH=1 # Use values 3 and 5 for different beam widths RUNNER=neural METHOD=l2c_rank NUM_WORKERS=4 # For parallel execution of queries python -m MPE.evaluation.evaluate --network-name $NETWORK_NAME --num-cases 1000 --num-workers $NUM_WORKERS --qr 0.75 --out-file results.json --runner $RUNNER --config-name $METHOD --depth $DEPTH --beam-width $WIDTH --run-daoopt
-
To run the evalution, please execute the following block.
RUNNER=neural_search METHOD=l2c_rank NUM_WORKERS=4 # For parallel execution of queries python -m MPE.evaluation.evaluate --network-name $NETWORK_NAME --num-cases 1000 --num-workers $NUM_WORKERS --qr 0.75 --out-file results.json --runner $RUNNER --config-name $METHOD
We set a timelimit of 60 seconds for every query. The solver statistics for each query will be checkpointed at 10, 30 and 60 seconds. The output containing the solver statistics for each of the queries will be saved at MPE/dataset/$NETWORK_NAME/testing-artifacts/timelimit-expts/$ORACLE/$RUNNER/$METHOD for every timelimit checkpoint where $ORACLE value is scip and daoopt for respective experiments.