ALF

ALF is an active learning framework for computational science, built to optimise high-dimensional search spaces where data acquisition is expensive—wet-lab experiments, physical measurements, or costly simulations. It accelerates the discovery of optimal designs (proteins, molecules, materials) through intelligent candidate selection, adaptive modelling, and efficient evaluation.

The ALF active learning loop

Note

This project is under active development.

🔬 Why ALF?

In scientific discovery, the bottleneck is rarely compute—it’s the experiment. Each label costs a wet-lab assay, a simulation, or a measurement, and you can only afford a handful of rounds. ALF runs the full active-learning loop: train a surrogate on what you’ve measured, use an acquisition function to select the most informative next batch, score it, and repeat—all with modular, swappable components so you can change any one part without rewriting the rest.

→ See Why ALF? for the full motivation and design rationale.

🗺️ Start here

Tutorials

Learning-oriented walkthroughs that take you from zero to a running experiment.

Tutorials
How-to / Recipes

Task-oriented recipes: add your own model, dataset, acquisition or search function.

How-to / Recipes
Explanation

The concepts: why ALF exists, the active-learning loop, and the objects that implement it.

Explanation
Reference

API reference generated from docstrings, plus a glossary of ALF terms.

Reference

📦 Installation

# Core package (minimal dependencies, no PyTorch required)
pip install alf-core

# Tools package (includes PyTorch, models, and datasets)
pip install alf-tools

For GPU support, optional extras, and development setup, see the Installation Guide.

🚀 Quick start

The snippet below runs a full active learning design experiment. Each component is swappable: bring your own dataset, model, acquisition function, or oracle.

What each component does:

  • Dataset — holds your candidates and their labels; handles train/candidate-pool splits

  • Surrogate — wraps a model that is cheaply re-trained each round to predict labels and uncertainty

  • Optimizer — scores the candidate pool with an acquisition function and selects the next batch

  • Oracle — evaluates selected candidates (wet-lab assay, simulation, or held-out dataset)

from alf_core import (
    BaseDatasetConfig,
    DatasetSearch,
    DesignTask,
    Optimizer,
    Oracle,
    Surrogate,
    TerminalStateLogger,
)
from alf_tools.datasets.gfp import GFP
from alf_tools.models.cnn import CNNModel
from alf_tools.optimizer.acquisition_functions.greedy import Greedy

# A dataset wraps your candidates and their known labels. A small train_ratio
# leaves a large candidate pool for the active-learning loop to acquire from.
config = BaseDatasetConfig(
    name="gfp",
    modality="sequence",
    seed=42,
    train_ratio=0.1,
    validation_frac=0.5,
    test_ratio=0.2,
    split_type="random",
    problem_type="regression",
)
dataset = GFP(config)

# The surrogate is a cheap probabilistic model trained on observed labels
surrogate = Surrogate(model=CNNModel())

# The optimizer picks the next batch: acquisition function scores candidates,
# search function selects from them
optimizer = Optimizer(acquisition_fn=Greedy(), search_fn=DatasetSearch())

# The oracle scores selected candidates (here, it queries the held-out dataset)
oracle = Oracle(scorer=dataset)

# Run the active learning loop for 5 rounds, acquiring 100 candidates per round
task = DesignTask(num_acq_rounds=5, acq_batch_size=100)
state = task.setup(dataset=dataset, surrogate=surrogate)
task.run(
    state=state,
    state_loggers=[TerminalStateLogger()],
    optimizer=optimizer,
    oracle=oracle,
)

New to active learning? Start with Why ALF? for the motivation, then work through the Tutorials.