Search Space Basics#
This chapter covers the implementation of search space for hyperparameter optimization
The search space refers to the range of values that can be used to explore each hyperparameter during HPO.
SearchSpace Class#
The SearchSpace
class in the Ablator library is responsible for defining the search space for hyperparameters. It allows you to specify the range for continuous hyperparameters, the categorical values for discrete hyperparameters, and the data type of the hyperparameter.
Import SearchSpace
using from ablator.main.configs import SearchSpace
.
The SearchSpace class takes the following arguments:
value_range: This argument is used to define the range for continuous hyperparameters. It is specified in the format of [lower_bound, upper_bound]. For example, you may set value_range = [0, 1.0] for the dropout layer.
categorical_values: This argument is used for discrete hyperparameters. For example, to test the model’s performance on different batch sizes, we can use categories like [32, 64, 128], etc.
value_type: This argument defines the data type of the hyperparameter. There are two data types supported: “int” for integer values and “float” for decimal or floating-point values. For example, value_type = “int” for integer type.
Note that categorical values do not require a value type.
from ablator.main.configs import SearchSpace
SearchSpace(value_range=[0.05, 0.1], value_type="float")
SearchSpace(categorical_values=[32, 64, 128])
Creating a search space for hyperparameters.#
The goal of defining a search space in hyperparameter optimization (HPO) is to encapsulate the possible values and ranges of hyperparameters.
We use a Python dictionary where the key represents a hyperparameter in the config object, and the value is the SearchSpace
object.
search_space_lr = {
"train_config.optimizer_config.arguments.lr": SearchSpace(
value_range=[0.05, 0.1], value_type="float"
)
}
Ablator can provide SearchSpace
for:
Predefined Configurations in Ablator: Ablator offers predefined configurations for optimizers, schedulers, batch size, epochs, and more. These configurations are readily available for users to use in their experiments.
Custom Configurations added by users: Users can define custom configurations for parameters specific to their experiments. For example, parameters of custom models, activation functions, dropout layers, and other relevant hyperparameters.
Using “SearchSpace” for predefined configurations#
With optimizers
The ablator provides three predefined optimizers with their arguments. [SGD, Adam, and AdamW].
Note: You can find all the default values for each optimizer in the “Configuration Basics” chapter.
Specifically for AdamW, a search space may be:
search_space = {
"train_config.optimizer_config.arguments.lr": SearchSpace(
value_range = [0.01, 0.05],
value_type = "float"
),
"train_config.optimizer_config.arguments.eps": SearchSpace(
value_range = [1e-9, 1e-7],
value_type = "float"
),
"train_config.optimizer_config.arguments.weight_decay": SearchSpace(
value_range = [1e-4, 1e-3],
value_type = "float"
),
}
With schedulers
The ablator also provides three schedulers: [step, cycle, and plateau]. You can use the SearchSpace
with schedulers for their respective arguments.
For example, a search_space
for scheduler “plateau” will look like this:
search_space = {
"train_config.scheduler_config.arguments.min_lr": SearchSpace(
value_range = [1e-6, 1e-4],
value_type = "float"
),
"train_config.scheduler_config.arguments.mode": SearchSpace(
categorical_values = ["min", "max", "auto"]
),
"train_config.scheduler_config.arguments.threshold": SearchSpace(
value_range = [1e-5, 1e-3],
value_type = "float"
),
}
Other parameters
We can also provide SearchSpace
to other parameters like epochs, batch_size, etc. inside train_config
.
For example, trying different batch_size or epochs can be easily done using the code:
search_space = {
"train_config.batch_size": SearchSpace(
categorical_values = [32, 64, 128]
),
"train_config.epochs": SearchSpace(
value_range = [10, 20],
value_type = "int"
),
}
Using SearchSpace for Custom Configs#
In this example, we will explore the “hidden_size” and “activation” parameters of a custom model and will create a search space for it.
Suppose, a custom model config takes some inputs like:
class CustomModelConfig(ModelConfig):
...
input_size :int
hidden_size :int
num_classes :int
activation: str
...
model_config = CustomModelConfig(
input_size = 28*28,
hidden_size = 256,
num_classes = 10,
activation = "relu"
)
Remember, a model config is defined to pass its arguments inside the constructor of the PyTorch model. For example:
class MyModel(nn.Module):
def __init__(self, config: CustomModelConfig) -> None:
activation_list = {"relu" : nn.ReLU(), "elu": nn.ELU()}
self.fc1 = nn.Linear(config.input_size, config.hidden_size)
self.act1 = activation_list[config.activation]
...
We can provide a SearchSpace
for model’s “hidden_size” parameter like this:
search_space = {
"model_config.hidden_size": SearchSpace(
value_range=[250, 500], value_type="int"
),
}
Similarly, we can also provide a search space for “activation”.
search_space = {
"model_config.activation": SearchSpace(
categorical_values = ["relu","elu"]
),
}
The ablator will create trials using different “hidden_size” or “activations” according to the “search_space” provided.
Finally, the search_space
dictionary is passed to the ParallelConfig, which will be explored in detail in the HPO tutorial.
SearchSpace for YAML files#
If we are using a YAML file to define configurations, we can specify a search space as follows:
...
search_space:
model_config.hidden_size:
value_range:
- '250'
- '500'
categorical_values: null
value_type: int
train_config.optimizer_config.arguments.lr:
value_range:
- '0.001'
- '0.01'
categorical_values: null
value_type: float
model_config.activation:
value_range: null
categorical_values:
- relu
- leakyRelu
- elu
value_type: float
...
Conclusion#
We have successfully explored the SearchSpace
class and various ways to utilize it. In the subsequent chapter, we will learn how to use search_space
with “ParallelConfig” for HPO.