Skip to content

cleverhans-lab/optifluence

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OptiFluence

Website

optifluence is the research codebase for OptiFluence: Principled Design of Privacy Canaries (ICML 2026).

@inproceedings{
yaghini2026optifluence,
title={OptiFluence: Principled Design of Privacy Canaries},
author={Mohammad Yaghini and Michael Aerni and Junrui Zhang and Nicolas Papernot and Florian Tram{\`e}r},
booktitle={Forty-third International Conference on Machine Learning},
year={2026},
url={https://openreview.net/forum?id=428khNRrGI}
}

Environment setup

  1. Install uv, then install all dependencies (Python version and packages are pinned by pyproject.toml / uv.lock):

    uv sync
  2. Create your environment file:

    cp template.env .env

    Set DATA_ROOT to the directory where datasets should live (defaults to src/utils/data if unset). MNIST, CIFAR-10, and CIFAR-100 are downloaded automatically on first use. HAM10000 must be downloaded manually into $DATA_ROOT/HAM10000/ (containing HAM10000_images_part_1/, HAM10000_images_part_2/, and HAM10000_metadata.csv), either from the Harvard Dataverse or via Kaggle: kaggle datasets download -d kmader/skin-cancer-mnist-ham10000.

  3. If you are running on a Slurm cluster, you may need an account for sbatch. The submit scripts add the #SBATCH --account line only when this is set:

    export SLURM_ACCOUNT=<your-allocation>

OptiFluence pipeline

Each dataset folder under src/experiments/ contains the id, mislabeled, adversarial, IF-Init, and OptiFluence canary experiments, plus ablations for CIFAR-10 and MNIST. We provide bash scripts that run all experiments; run each step in order and wait for its jobs to finish (squeue -u $USER) before launching the next:

cd src/experiments/<dataset>   # mnist, cifar100, cifar10_resnet9, cifar10_ema, or ham10k

./submit_0_preselection.sh     # step 0: influence-based canary preselection (IF-Init)
./submit_1_optimize.sh         # step 1: optimize canaries (baseline canaries skip this step)
./submit_2_init_canaries.sh    # step 2: initialize canaries
./submit_3_train_eval.sh       # step 3: train target/shadow models
./submit_4_attack.sh           # step 4: LiRA membership inference attack

Notes:

  • Step 0 writes the ranked canary indices to preselection/canary_selection.json; steps 1-3 read the top-k indices from this file for the IF-Init and OptiFluence experiment groups (seed i uses the i-th index).
  • cifar10_ema reuses cifar10_resnet9/preselection/canary_selection.json.
  • Step 3 submits one array job per experiment dir and is resumable: rerun the script after failures or timeouts and completed models are skipped.
  • Step 4 writes attack results to attack_results.npz inside each experiment directory.
  • To plot the results, see examples/plots.ipynb.

Additional experiments

The dp/, transferability/, and full_base_attack/ folders reuse canaries from the main experiments instead of optimizing their own, so steps 0-2 are replaced by a single copy script:

cd src/experiments/<experiment>   # dp/mnist, dp/cifar10, transferability/mnist,
                                  # transferability/cifar10, or full_base_attack

./copy_canaries.sh             # copy canaries from the main experiments
./submit_3_train_eval.sh       # train target/shadow models
./submit_4_attack.sh           # LiRA membership inference attack

Run the corresponding main experiment (e.g. mnist or cifar10_resnet9) through step 2 first, since copy_canaries.sh reads its canary files and submit_3_train_eval.sh reads its preselection/canary_selection.json.

  • dp/: the DP-SGD sweep; each OptiFluence_<i> variant differs only in the noise multiplier in its config.json (generate_eps.py maps target epsilons to noise multipliers).
  • transferability/: the same canary attacked across model architectures (CIFAR-10) or MLP widths (MNIST).
  • full_base_attack/: ablation with sample_non_canaries=false, i.e. models train on the full non-canary pool instead of 50-50 splits.

Running a single experiment manually

All commands are run from the repository root with PYTHONPATH=src.

0. Canary preselection

PYTHONPATH=src uv run python -m eval.eval_select \
    --dir src/experiments/cifar10_resnet9/preselection \
    --num_models 5

1. Optimize canary

This step is only needed for optimized canaries.

JAX_PLATFORMS=cuda PYTHONPATH=src uv run python -m eval.eval_optimize \
    --dir src/experiments/cifar10_resnet9/OptiFluence_0 \
    --canary_indices 0 --manual_canary_selection <CANARY_IDX>

2. Initialize canary

JAX_PLATFORMS=cuda PYTHONPATH=src uv run python -m eval.generate_baseline_canaries \
    --dir src/experiments/cifar10_resnet9/OptiFluence_0 \
    --manual_canary_selection <CANARY_IDX>

3. Train eval models

The --model-indices range is end-exclusive and must cover all target + shadow models; e.g., for 1000 target + 128 shadow models, use --model-indices 0-1128.

JAX_PLATFORMS=cuda PYTHONPATH=src uv run python -m eval.eval_train \
    --resume --no-store-models \
    --dir src/experiments/cifar10_resnet9/OptiFluence_0 \
    --model-indices <START_IDX>-<END_IDX> \
    --manual_canary_selection <CANARY_IDX>

4. Membership inference attack

PYTHONPATH=src uv run python -m eval.eval_attack \
    --dir src/experiments/cifar10_resnet9/OptiFluence_0

Results are written to attack_results.npz in the experiment directory.

Acknowledgements

Parts of this codebase are adapted from misleading-privacy-evals (attack utilities and evaluation design), CleverHans (adversarial example generation), and hlb-CIFAR10 (fast CIFAR training used for influence computation).

License

This project is licensed under the MIT License.

About

Optimized Privacy Canaries

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors