Configurability determines which training-pipeline behaviors can change through explicit settings instead of fixed implementation choices. Too little configurability makes datasets, preprocessing, and model changes difficult; too much adds abstraction and complexity. section 10.4
Balance configurability by making likely changes easy and unlikely changes uncomplicated:
- Expose datasets and other frequently changed pipeline inputs as configuration. section 10.4
- Avoid hardcoded values and convoluted structure that make simple changes difficult. section 10.4
- Resist configuration layers for every conceivable use case; unnecessary abstractions increase complexity. section 10.4
- Test changes to catch regression bugs, improve iteration speed, and reveal whether the configuration design is balanced. section 10.7
Listing 10.1 Multilevel hierarchy of subcodings
def train():
...
batch_size = 32
...
learning_rate = 3e-4
...
model.train(data, batch_size, loss_fn)
...
^ example of underconfigured code: things are too rigid
class Config(BaseConfig):
def __init__(self):
self.data_config = DataConfig()
self.model_config = ModelConfig()
self.training_config = TrainingConfig()
self.inference_config = InferenceConfig()
self.environment_config = EnvironmentConfig()
class DataConfig(BaseConfig):
def __init__(self):
self.train_data_config = TrainDataConfig()
self.validation_data_config = ValidationDataConfig()
self.test_data_config = TestDataConfig()
config = Config(
data_config=DataConfig(
train_data_config=TrainDataConfig(
...
),
validation_data_config=ValidationDataConfig(
...
),
test_data_config=TestDataConfig(
...
),
),
...
)
Compare rigid hardcoded training values with a multilevel configuration hierarchy, then judge which structure adds useful flexibility rather than needless indirection. section 10.4
