Single Objective Optimization
In the following, a Single-Input-Single-Output (SISO) function is optimized.
The function that we will be optimizing is:
which is a maximization problem where the parameter x has a range of 0 to 10, and the optimum point is at x^* = 5.14574 and f(x^*) = 1.8996.
1. Import the necessary packages
1 2 3 4 5 6 7 8 |
|
2. Define the function and the objective
The function is defined, and a noise_level
parameter is added to implement some measurement noise.
1 2 3 |
|
3. Visualize the function
Now some ground truth data is created to see what the function looks like. This is done by creating 1000 points evenly distributed in the parameter space, without any noise.
1 2 |
|
For the purposes of the optimization, the noise_level
parameter will be set to 0.2, and the real_func
function is wrapped by the Objective
class to define the objective.
1 2 |
|
1 2 3 4 5 6 7 8 9 |
|
Output
4. Define the Mission
In this case, we have a Mission with one input dimension and one output dimension. The param_space
for the single input variable is 0 to 10, and as this is a maximization function, the goal is to ascend.
1 2 3 4 5 6 7 8 9 |
|
5. Define the navigator
We want to initialize the model with 4 initial points, defined by the num_init_design
variable, and the SingleGP_Navigator
well suited as the navigator, as this is a single objective problem. Additionally, the UpperConfidenceBound
(UCB) acquisition function is used with the beta
parameter set to 0.5.
1 2 3 4 5 6 7 8 9 10 11 |
|
6. Visualize the initial points
The points investigated so far are available in the mission
object:
1 2 |
|
Output
>>> tensor([[0.3935],
[3.8459],
[5.3469],
[7.4725]])
tensor([[-1.2596],
[ 0.4513],
[ 1.6862],
[-0.9045]])
A plot is now created with the initial points:
1 2 3 4 5 6 7 8 9 10 |
|
Output
7. Run the optimization loop
The num_iter
variable defines the number of iterations to run, and is set to 10. Some additional packages are imported here to filter out any warnings that might arise during the loop. The intermediate trajectories and observations are printed while the loop runs.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Expand to see Output
>>> 0 tensor([[5.2228]]) tensor([[1.7943]])
Succesfully appended {'param_1': [5.222783697804586], 'objective_1': [1.7942542090001241], 'creation_timestamp': '07-06-24 20:42:18'} to missionlogs/siso_test-070624_204218.csv
1 tensor([[5.0633]]) tensor([[1.6669]])
Succesfully appended {'param_1': [5.063268220232772], 'objective_1': [1.6669435062813764], 'creation_timestamp': '07-06-24 20:42:18'} to missionlogs/siso_test-070624_204218.csv
2 tensor([[5.2090]]) tensor([[2.0303]])
Succesfully appended {'param_1': [5.209039917615592], 'objective_1': [2.030305338216286], 'creation_timestamp': '07-06-24 20:42:19'} to missionlogs/siso_test-070624_204218.csv
3 tensor([[5.2030]]) tensor([[2.0740]])
Succesfully appended {'param_1': [5.20300015093294], 'objective_1': [2.073958124226767], 'creation_timestamp': '07-06-24 20:42:19'} to missionlogs/siso_test-070624_204218.csv
4 tensor([[5.1981]]) tensor([[1.7659]])
Succesfully appended {'param_1': [5.198063877181482], 'objective_1': [1.7658530056055226], 'creation_timestamp': '07-06-24 20:42:19'} to missionlogs/siso_test-070624_204218.csv
5 tensor([[5.2057]]) tensor([[1.8139]])
Succesfully appended {'param_1': [5.205699318922052], 'objective_1': [1.813869009628372], 'creation_timestamp': '07-06-24 20:42:19'} to missionlogs/siso_test-070624_204218.csv
6 tensor([[5.2067]]) tensor([[1.7615]])
Succesfully appended {'param_1': [5.206695536261849], 'objective_1': [1.7615019525702753], 'creation_timestamp': '07-06-24 20:42:19'} to missionlogs/siso_test-070624_204218.csv
7 tensor([[5.2078]]) tensor([[1.7921]])
Succesfully appended {'param_1': [5.207809210199016], 'objective_1': [1.7920781084517736], 'creation_timestamp': '07-06-24 20:42:19'} to missionlogs/siso_test-070624_204218.csv
8 tensor([[5.2079]]) tensor([[1.6780]])
Succesfully appended {'param_1': [5.207949576707767], 'objective_1': [1.677978183918718], 'creation_timestamp': '07-06-24 20:42:19'} to missionlogs/siso_test-070624_204218.csv
9 tensor([[5.2089]]) tensor([[1.8183]])
Succesfully appended {'param_1': [5.20894024902588], 'objective_1': [1.8183155492649645], 'creation_timestamp': '07-06-24 20:42:19'} to missionlogs/siso_test-070624_204218.csv
8. Visualize the iterated points and uncertainty
To find the uncertainty, the posterior mean and standard deviation need to be found. These can be calculated using the model
attribute of the navigator
object. The posterior model is always set up for a maximization, so if you have a minimization problem, simply add a minus (-) before the pred_mean
.
1 2 3 |
|
Now a plot can be generated with the function, noise band, iterated points, posterior model and uncertainty:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Output
Notice how the posterior model has a better mean and lower uncertainty around the observed points!
9. Analyze the results
The results can be analyzed by finding the iterated point with the highest output value, as this is a maximization problem:
1 2 3 4 5 6 |
|
Output
>>> Best Input: 5.20300015093294
Best Output: 2.073958124226767
Looking at the final plot, it does seem that the best observed point is right on the upper limit of the noise band - this explains the slightly higher optimal value. Nonetheless, with just 4 random iterations and 10 optimization iterations, we have come fairly close to the optimum point.