3.1. Configuration classes

Throughout this guide we have mostly passed raw objects to ClinicaDL (e.g; TorchIO transforms, PyTorch losses and networks). This is convenient, but raw objects have a drawback for reproducibility: ClinicaDL cannot always inspect them to know exactly how they were parametrised, nor rebuild them later from a saved experiment.

This is the problem configuration classes solve.

3.1.1. What is a configuration class?

A configuration class is a small dataclass associated with a Python object. It holds only the parameters of that object, with almost no logic of its own. From a configuration object, you obtain the actual object with its get_object method.

For instance, instead of building an optimizer directly, you describe it with AdamConfig:

from clinicadl.optim.optimizers.config import AdamConfig

config = AdamConfig(lr=1e-4)

optimizer = config.get_object(network=network)   # the underlying torch.optim.Adam

Because a configuration class contains only data, it can be saved and read back, which a raw object generally cannot:

config.to_json("adam.json")
config = AdamConfig.from_json("adam.json")

This is exactly what makes an experiment reproducible: ClinicaDL stores the configuration of every object it uses, so the whole setup can be rebuilt later (see MAPS).

Note

The objects implemented in ClinicaDL have internal configuration classes that are not directly visible to the user. You will mostly manipulate configuration classes associated to objects that come from external libraries (PyTorch, MONAI, etc.).

3.1.2. Where you can use them

Wherever ClinicaDL accepts a raw object, it usually also accepts the matching configuration class. Configuration classes exist for the main building blocks of the library:

Module

Covers

clinicadl.networks.config

Neural networks (e.g. VAEConfig)

clinicadl.losses.config

Loss functions (e.g. CrossEntropyLossConfig)

clinicadl.optim.optimizers.config

Optimizers (e.g. AdamConfig)

clinicadl.optim.lr_schedulers.config

Learning-rate schedulers (e.g. OneCycleLRConfig)

clinicadl.transforms.config

Transforms — preprocessing, augmentation, post-processing (e.g. CropOrPadConfig)

clinicadl.metrics.config

Metrics (e.g. DiceMetricConfig)

As an example, a TransformsHandler can be built from raw TorchIO transforms or from their configuration classes — the two are equivalent, but only the second is fully reproducible:

import torchio as tio
from clinicadl.transforms import TransformsHandler
from clinicadl.transforms.config import ZNormalizationConfig

# with a raw transform ...
transforms = TransformsHandler(image_transforms=[tio.ZNormalization()])

# ... or with its configuration class
transforms = TransformsHandler(image_transforms=[ZNormalizationConfig()])

Tip

To get the most reproducible experiments, prefer configuration classes over raw objects wherever one exists.

Note

The list of available configuration classes is not exhaustive — it covers mostly the objects coming from PyTorch, MONAI and TorchIO — but it keeps growing. When no configuration class exists for an object, you can still use the raw object; only that object will not be reproducible by ClinicaDL.


Configuration classes are what allows the MAPS to record a complete, reproducible description of your experiment.