@@ -11,7 +11,7 @@ Status](https://codecov.io/gh/AnotherSamWilson/ParBayesianOptimization/branch/ma
1111
1212# Parallelizable Bayesian Optimization
1313
14- <a href = ' https://github.com/AnotherSamWilson/ParBayesianOptimization ' >< img src =' icon.png ' align = ' right ' height =" 400 " /></ a >
14+ <img src =' man/figures/ icon.png' align = ' right ' height =" 300 " />
1515
1616This README contains a thorough walkthrough of Bayesian optimization and
1717the syntax needed to use this package, with simple and complex examples.
@@ -34,7 +34,9 @@ More information can be found in the package vignettes and manual.
3434 - [ 07 - Sampling Multiple Promising Points at
3535 Once] ( https://github.com/AnotherSamWilson/ParBayesianOptimization#Sampling-Multiple-Promising-Points-at-Once )
3636 - [ 08 - How Long Should it Run
37- For?] ( https://github.com/AnotherSamWilson/ParBayesianOptimization#how-long-should-it-run-for )
37+ For?] ( https://github.com/AnotherSamWilson/ParBayesianOptimization#how-long-should-it-run-for )
38+ - [ 09 - Setting Stopping
39+ Criteria] ( https://github.com/AnotherSamWilson/ParBayesianOptimization#Setting-Time-Limits-and-Other-Halting-Criteria )
3840
3941## Installation
4042
@@ -157,7 +159,9 @@ xmax <- optim(8,simpleFunction,method = "L-BFGS-B",lower = 0, upper = 15,control
157159library(ggplot2 )
158160ggplot(data = data.frame (x = c(0 ,15 )),aes(x = x )) +
159161 stat_function(fun = simpleFunction ) +
160- geom_vline(xintercept = xmax ,linetype = " dashed" )
162+ geom_vline(xintercept = xmax ,linetype = " dashed" ) +
163+ ggtitle(" simpleFunction" ) +
164+ theme_bw()
161165```
162166
163167![ ] ( man/figures/README-simpleFunction-1.png ) <!-- -->
@@ -190,31 +194,30 @@ optObjSimp <- bayesOpt(
190194 , iters.n = 2
191195 , gsPoints = 25
192196)
193- # > Warning: package 'DiceKriging' was built under R version 3.6.2
194197```
195198
196199Let’s see how close the algorithm got to the global maximum:
197200
198201``` r
199202getBestPars(optObjSimp )
200203# > $x
201- # > [1] 6.448408
204+ # > [1] 7.110515
202205```
203206
204207The process is getting pretty close\! We were only about 11% shy of the
205208global optimum:
206209
207210``` r
208211simpleFunction(7.023 )/ simpleFunction(getBestPars(optObjSimp )$ x )
209- # > [1] 1.116824
212+ # > [1] 1.002635
210213```
211214
212215Let’s run the process for a little longer:
213216
214217``` r
215218optObjSimp <- addIterations(optObjSimp ,iters.n = 3 ,verbose = 0 )
216219simpleFunction(7.023 )/ simpleFunction(getBestPars(optObjSimp )$ x )
217- # > [1] 1.00002
220+ # > [1] 1.002635
218221```
219222
220223We have now found an ` x ` very close to the global optimum.
@@ -312,15 +315,15 @@ to see the results:
312315
313316``` r
314317optObj $ scoreSummary
315- # > Epoch Iteration max_depth min_child_weight subsample gpUtility acqOptimum inBounds Elapsed Score nrounds
316- # > 1: 0 1 2 1.670129 0.7880670 NA FALSE TRUE 0.10 0.9777163 2
317- # > 2: 0 2 2 14.913213 0.8763154 NA FALSE TRUE 0.28 0.9763760 15
318- # > 3: 0 3 4 18.833690 0.3403900 NA FALSE TRUE 0.44 0.9931657 18
319- # > 4: 0 4 4 8.639925 0.5499186 NA FALSE TRUE 0.25 0.9981437 7
320- # > 5: 1 5 4 21.871937 1.0000000 0.5857961 TRUE TRUE 0.14 0.9945933 1
321- # > 6: 2 6 5 2.051363 0.7528395 0.4650739 TRUE TRUE 0.38 0.9984613 11
322- # > 7: 3 7 4 0.000000 1.0000000 0.4653549 TRUE TRUE 0.23 0.9941097 6
323- # > 8: 4 8 5 25 .000000 0.6339013 0.3995827 TRUE TRUE 0.18 0.9943380 3
318+ # > Epoch Iteration max_depth min_child_weight subsample gpUtility acqOptimum inBounds Elapsed Score nrounds errorMessage
319+ # > 1: 0 1 2 1.670129 0.7880670 NA FALSE TRUE 0.13 0.9777163 2 NA
320+ # > 2: 0 2 2 14.913213 0.8763154 NA FALSE TRUE 0.28 0.9763760 15 NA
321+ # > 3: 0 3 4 18.833690 0.3403900 NA FALSE TRUE 0.47 0.9931657 18 NA
322+ # > 4: 0 4 4 8.639925 0.5499186 NA FALSE TRUE 0.27 0.9981437 7 NA
323+ # > 5: 1 5 4 21.871937 1.0000000 0.5857961 TRUE TRUE 0.14 0.9945933 1 NA
324+ # > 6: 2 6 4 0.000000 0.9439879 0.6668303 TRUE TRUE 0.26 0.9990567 7 NA
325+ # > 7: 3 7 5 1.395119 0.7071802 0.2973497 TRUE TRUE 0.23 0.9984577 4 NA
326+ # > 8: 4 8 5 0 .000000 0.2500000 0.3221660 TRUE TRUE 0.36 0.9994020 10 NA
324327```
325328
326329``` r
@@ -329,10 +332,10 @@ getBestPars(optObj)
329332# > [1] 5
330333# >
331334# > $min_child_weight
332- # > [1] 2.051363
335+ # > [1] 0
333336# >
334337# > $subsample
335- # > [1] 0.7528395
338+ # > [1] 0.25
336339```
337340
338341## Running In Parallel
@@ -379,33 +382,36 @@ optimization steps, versus the 4 performed in the sequential example:
379382``` r
380383tWithPar
381384# > user system elapsed
382- # > 1.59 0.25 6.03
385+ # > 1.37 0.05 10.00
383386tNoPar
384387# > user system elapsed
385- # > 16.74 2.02 16.44
388+ # > 23.17 2.47 22.56
386389```
387390
388391## Sampling Multiple Promising Points at Once
389392
390- Sometimes we may want to sample multiple promising parameter sets at the
391- same time. This is especially effective if the process is being run in
392- parallel. The ` bayesOpt ` function always samples the global optimum of
393- the acquisition function, however it is also possible to tell it to
394- sample local optimums of the acquisition function at the same time.
393+ Sometimes we may want to sample multiple promising points at the same
394+ optimization step (Epoch). This is especially effective if the process
395+ is being run in parallel. The ` bayesOpt ` function always samples the
396+ global optimum of the acquisition function, however it is also possible
397+ to tell it to sample local optimums of the acquisition function at the
398+ same time.
395399
396400Using the ` acqThresh ` parameter, you can specify the minimum percentage
397401utility of the global optimum required for a different local optimum to
398- be considered. As an example, let’s say we are optimizing 1
399- hyperparameter ` min_child_weight ` , which is bounded between \[ 0,5 \] . Our
400- acquisition function may look like the following:
402+ be considered. As an example, let’s say we are optimizing 1 input ` x ` ,
403+ which is bounded between \[ 0,1 \] . Our acquisition function may look like
404+ the following:
401405
402406<img src =" vignettes/UCB.png " width =" 600px " style =" display : block ; margin : auto ;" />
403407
404- In this case, there are 3 promising candidate parameters. We may want to
405- run our scoring function on several of the local maximums. If
406- ` acqThresh ` is set to be below \~ 0.95, and ` iters.k ` is set to at least
407- 3, the process would use all 3 of the local maximums as candidate
408- parameter sets in the next round of scoring function runs.
408+ In this case, there are 3 promising candidate parameters: x \~
409+ \[ 0.318,0.541,0.782\] with corresponding upper confidence bounds of y \~
410+ \[ 1.195,1.304,1.029\] , respectively. We may want to run our scoring
411+ function on several of the local maximums. If ` acqThresh ` is set to be
412+ below 1.029/1.304 \~ 0.789 and ` iters.k ` is set to at least 3, the
413+ process would use all 3 of the local maximums as candidate parameter
414+ sets in the next round of scoring function runs.
409415
410416## How Long Should it Run For?
411417
@@ -428,3 +434,33 @@ better parameter set than the one you already have. Notice that the
428434expected improvement converged to 0 after iteration 5. If you see a
429435similar pattern, you can be fairly certain that you have found an
430436(approximately) global optimum.
437+
438+ ## Setting Time Limits and Other Halting Criteria
439+
440+ Many times the scoring function can vary in its completion time. It may
441+ be difficult for the user to forecast how long a single run will take,
442+ let alone X sequential runs. For this reason, you can set a time limit.
443+ You can also set a minimum utility limit, or you can set * both* , in
444+ which case the process stops when either condition is met. You can see
445+ how the process stopped by viewing the ` stopStatus ` element in the
446+ returned object:
447+
448+ ``` r
449+ set.seed(0 )
450+
451+ tNoPar <- system.time(
452+ optObj <- bayesOpt(
453+ FUN = scoringFunction
454+ , bounds = bounds
455+ , initPoints = 4
456+ , iters.n = 400
457+ , iters.k = 1
458+ , otherHalting = list (timeLimit = 5 )
459+ )
460+ )
461+
462+ optObj $ stopStatus
463+ # > [1] "Time Limit - 5 seconds."
464+ # > attr(,"class")
465+ # > [1] "stopEarlyMsg"
466+ ```
0 commit comments