Experiment
Module containing the functions which create experiment components from Hydra configs.
This is essentially just calling hydra.utils.instantiate on the datamodule, network, trainer, and algorithm configs in a certain order.
This also adds the instance_attr custom resolver, which allows you to retrieve an attribute of an instantiated object instead of a config.
Experiment
dataclass
#
Dataclass containing everything used in an experiment.
This gets created from the config that are parsed from Hydra. Can be used to run the experiment
by calling run(experiment)
. Could also be serialized to a file or saved to disk, which might
come in handy with submitit
later on.
setup_experiment #
setup_experiment(experiment_config: Config) -> Experiment
Instantiate the experiment components from the Hydra configuration.
All the interpolations in the configs have already been resolved by project.utils.hydra_utils.resolve_dictconfig. Now we only need to instantiate the components from their configs.
Do all the postprocessing necessary (e.g., create the network, datamodule, callbacks,
Trainer, Algorithm, etc) to go from the options that come from Hydra, into all required
components for the experiment, which is stored as a dataclass called Experiment
.
NOTE: This also has the effect of seeding the random number generators, so the weights that are constructed are deterministic and reproducible.
instantiate_datamodule #
instantiate_datamodule(
datamodule_config: (
Builds[type[DataModule]] | DataModule
),
) -> DataModule
Instantiate the datamodule from the configuration dict.
Any interpolations in the config will have already been resolved by the time we get here.
instantiate_algorithm #
instantiate_algorithm(
algorithm_config: Config, datamodule: DataModule
) -> LightningModule
Function used to instantiate the algorithm.
It is suggested that your algorithm (LightningModule) take in the datamodule
and network
as arguments, to make it easier to swap out different networks and datamodules during
experiments.
The instantiated datamodule and network will be passed to the algorithm's constructor.
instantiate_network_from_hparams #
instantiate_network_from_hparams(
network_hparams: Dataclass, datamodule: DataModule
) -> Module
TODO: Refactor this if possible. Shouldn't be as complicated as it currently is.
Perhaps we could register handler functions for each pair of datamodule and network type, a bit like a multiple dispatch?