Configurations in Hyrax#
Hyrax uses configuration files to make it easier to track all of the parameters used for a given process. Hyrax attempts to provide a set of reasonable configuration values for all of the operations a user will perform, with exceptions.
When you create a Hyrax instance, the built in defaults will be used automatically.
[1]:
from hyrax import Hyrax
h = Hyrax()
Once a Hyrax instance is created, the configuration is available as the h.config dictionary. We can view any particular value by using the keys of the dictionary. For instance, if we wanted to know what the default filename will be for the trained model weights file, we can use the following:
[2]:
h.config["train"]["weights_filename"]
[2]:
'example_model.pth'
If you’re interested, the complete Hyrax default configuration file can be seen here: https://hyrax.readthedocs.io/en/latest/hyrax_default_config.html
A small portion of the default config can be seen below.
[3]:
import json
print(json.dumps(h.config["general"], indent=2))
{
"dev_mode": false,
"log_destination": "stderr",
"log_level": "info",
"data_dir": "/home/docs/checkouts/readthedocs.org/user_builds/hyrax/checkouts/v0.8.0/docs/notebooks/data",
"results_dir": "./results"
}
Updating config values#
While it is possible to set the values in the dictionaries directly, using h.set_config() will rerun the Hyrax configuration resolution algorithm to ensure that any secondary configuration updates are incorporated.
[4]:
print(f"Default number of epochs: {h.config['train']['epochs']}")
h.set_config("train.epochs", 5)
print(f"Updated number of epochs: {h.config['train']['epochs']}")
Default number of epochs: 10
Updated number of epochs: 5
Warning
Use caution with ``None`` When setting config values, it is generally a good idea to avoid using
None. It is preferable to useFalseor an empty string,""when using .toml.
User configuration files#
It is not always convenient to manually modify configurations each time Hyrax runs. Configurations can be overridden with a custom .toml file provided to Hyrax during instantiation.
In this example, we’ll name our file user_config.toml (any file name is fine), and set the log level and weights filename like so:
[general]
log_level = "error"
[train]
weights_filename = "model_weights.pth"
Note
User configuration files don’t need to be a complete copy of the default configuration file. Hyrax will start with the defaults and override the specific keys with values from the user’s configuration file.
[5]:
import json
h = Hyrax(config_file="./user_config.toml")
print("Only the log level has been changed in the 'general' section:")
print(json.dumps(h.config["general"], indent=2))
print("Additionally, the trained weights file name is now:")
print(h.config["train"]["weights_filename"])
Only the log level has been changed in the 'general' section:
{
"dev_mode": false,
"log_destination": "stderr",
"log_level": "error",
"data_dir": "/home/docs/checkouts/readthedocs.org/user_builds/hyrax/checkouts/v0.8.0/docs/notebooks/data",
"results_dir": "./results"
}
Additionally, the trained weights file name is now:
model_weights.pth
Config immutability#
To support reproducibility, once a Hyrax action starts, the configuration is locked. There are very few exceptions to this rule, and Hyrax clearly logs when the config does change. This ensures that when the config state is saved, it accurately represents the settings used by Hyrax.
The state of the configuration will always be saved alongside the output of a Hyrax action in a time stamped directory like YYYYmmdd-HHMMSS-train-RAND.
This is another way that Hyrax supports low-code experimentation with machine learning.