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 |
|---|---|
Neural networks (e.g. |
|
Loss functions (e.g. |
|
Optimizers (e.g. |
|
Learning-rate schedulers (e.g. |
|
Transforms — preprocessing, augmentation, post-processing (e.g. |
|
Metrics (e.g. |
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.