+
Skip to content

BREAKING CHANGE: replace adagio::pureCMAES() with cmaes::cma_es() #293

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Imports:
mlr3misc (>= 0.15.1),
R6
Suggests:
adagio,
cmaes,
emoa,
GenSA,
irace (>= 4.0.0),
Expand Down
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# bbotk (development version)

* BREAKING CHANGE: Replace `adagio::pureCMAES()` with `cmaes::cma_es()` in `OptimizerBatchCmaes`.

# bbotk 1.6.0

# bbotk 1.5.0
Expand Down
1 change: 0 additions & 1 deletion R/OptimInstanceBatch.R
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@ OptimInstanceBatch = R6Class("OptimInstanceBatch",

objective_function = function(x, inst, direction) {
xs = set_names(as.list(x), inst$search_space$ids())
inst$search_space$assert(xs)
xdt = as.data.table(xs)
res = inst$eval_batch(xdt)
y = as.numeric(res[, inst$objective$codomain$target_ids, with = FALSE])
Expand Down
86 changes: 54 additions & 32 deletions R/OptimizerBatchCmaes.R
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,36 @@
#' @name mlr_optimizers_cmaes
#'
#' @description
#' `OptimizerBatchCmaes` class that implements CMA-ES. Calls [adagio::pureCMAES()]
#' from package \CRANpkg{adagio}. The algorithm is typically applied to search
#' space dimensions between three and fifty. Lower search space dimensions might
#' crash.
#' `OptimizerBatchCmaes` class that implements CMA-ES.
#' Calls `cma_es()` from package \CRANpkg{cmaes}.
#' The algorithm is typically applied to search space dimensions between three and fifty.
#' Lower search space dimensions might crash.
#'
#' @templateVar id cmaes
#' @template section_dictionary_optimizers
#'
#' @section Parameters:
#' \describe{
#' \item{`sigma`}{`numeric(1)`}
#' \item{`start_values`}{`character(1)`\cr
#' Create `"random"` start values or based on `"center"` of search space?
#' In the latter case, it is the center of the parameters before a trafo is applied.
#' If set to `"custom"`, the start values can be passed via the `start` parameter.}
#' Create `"random"` start values or based on `"center"` of search space?
#' In the latter case, it is the center of the parameters before a trafo is applied.
#' If set to `"custom"`, the start values can be passed via the `start` parameter.}
#' \item{`start`}{`numeric()`\cr
#' Custom start values. Only applicable if `start_values` parameter is set to `"custom"`.}
#' Custom start values.
#' Only applicable if `start_values` parameter is set to `"custom"`.}
#' }
#'
#' For the meaning of the control parameters, see [adagio::pureCMAES()]. Note
#' that we have removed all control parameters which refer to the termination of
#' the algorithm and where our terminators allow to obtain the same behavior.
#' For the meaning of the control parameters, see `cma_es()`.
#' The parameters `maxit`, `stopfitness` and `stop.tolx` can be used additionally to our terminators.
#' The default values of `maxit` is `100 * D^2` where `D` is the number of dimensions of the search space.
#' The `stop.tolx` parameter stops when the step size is smaller than `1e-12 * sigma`.
#' The `vectorized` parameter is always set to `TRUE`.
#'
#' @template section_progress_bars
#'
#' @export
#' @examples
#' if (requireNamespace("adagio")) {
#' if (requireNamespace("cmaes")) {
#' search_space = domain = ps(
#' x1 = p_dbl(-10, 10),
#' x2 = p_dbl(-5, 5)
Expand Down Expand Up @@ -72,9 +74,26 @@ OptimizerBatchCmaes = R6Class("OptimizerBatchCmaes",
#' Creates a new instance of this [R6][R6::R6Class] class.
initialize = function() {
param_set = ps(
sigma = p_dbl(default = 0.5),
start_values = p_fct(default = "random", levels = c("random", "center", "custom")),
start = p_uty(default = NULL, depends = start_values == "custom")
fnscale = p_dbl(default = 1),
maxit = p_int(lower = 1L),
stopfitness = p_dbl(default = -Inf),
keep.best = p_lgl(default = TRUE),
sigma = p_uty(default = 0.5),
mu = p_int(lower = 1L),
lambda = p_int(lower = 1L),
weights = p_uty(),
damps = p_dbl(),
cs = p_dbl(),
ccum = p_dbl(),
ccov.1 = p_dbl(lower = 0),
ccov.mu = p_dbl(lower = 0),
diag.sigma = p_lgl(default = FALSE),
diag.eigen = p_lgl(default = FALSE),
diag.pop = p_lgl(default = FALSE),
diag.value = p_lgl(default = FALSE),
stop.tolx = p_dbl(), # undocumented stop criterion
start_values = p_fct(default = "random", levels = c("random", "center", "custom")),
start = p_uty(default = NULL, depends = start_values == "custom")
)
param_set$values$start_values = "random"
param_set$values$start = NULL
Expand All @@ -84,7 +103,7 @@ OptimizerBatchCmaes = R6Class("OptimizerBatchCmaes",
param_set = param_set,
param_classes = "ParamDbl",
properties = "single-crit",
packages = "adagio",
packages = "cmaes",
label = "Covariance Matrix Adaptation Evolution Strategy",
man = "bbotk::mlr_optimizers_cmaes"
)
Expand All @@ -94,29 +113,32 @@ OptimizerBatchCmaes = R6Class("OptimizerBatchCmaes",
private = list(
.optimize = function(inst) {
pv = self$param_set$values
start_values = pv$start_values
start = pv$start

if (pv$start_values == "custom") {
pv$par = pv$start
pv$start_values = NULL
pv$start = NULL
} else {
pv$par = search_start(inst$search_space, type = pv$start_values)
pv$start_values = NULL
pv$start = NULL
par = if (pv$start_values == "custom") set_names(start, inst$search_space$ids()) else search_start(inst$search_space, type = start_values)

if (length(par) < 2L) {
warning("CMA-ES is typically applied to search space dimensions between three and fifty. A lower search space dimension might crash.")
}

pv$stopeval = .Machine$integer.max # make sure pureCMAES does not stop
pv$stopfitness = -Inf
control = pv[names(pv) %nin% c("start_values", "start")]
control$vectorized = TRUE

if (length(pv$par) < 2L) {
warning("CMA-ES is typically applied to search space dimensions between three and fifty. A lower search space dimension might crash.")
wrapper = function(xmat, inst) {
xdt = as.data.table(t(xmat))
res = inst$eval_batch(xdt)
y = res[, inst$objective$codomain$target_ids, with = FALSE][[1]]
y * inst$objective_multiplicator
}

invoke(adagio::pureCMAES,
fun = inst$objective_function,
invoke(cmaes::cma_es,
par = par,
fn = wrapper,
lower = inst$search_space$lower,
upper = inst$search_space$upper,
.args = pv)
control = control,
inst = inst)
}
)
)
Expand Down
22 changes: 12 additions & 10 deletions man/mlr_optimizers_cmaes.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions tests/testthat/_snaps/OptimizerCmaes.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
Output

-- <OptimizerBatchCmaes> - Covariance Matrix Adaptation Evolution Strategy -----
* Parameters: start_values=random
* Parameters: mu=5, lambda=5, start_values=random
* Parameter classes: <ParamDbl>
* Properties: single-crit
* Packages: bbotk and adagio
* Packages: bbotk and cmaes

8 changes: 4 additions & 4 deletions tests/testthat/test_OptimizerCmaes.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
test_that("OptimizerBatchCmaes", {
skip_if_not_installed("adagio")
skip_if_not_installed("cmaes")

search_space = domain = ps(
x1 = p_dbl(-10, 10),
Expand All @@ -22,15 +22,15 @@ test_that("OptimizerBatchCmaes", {
search_space = search_space,
terminator = trm("evals", n_evals = 10L))

z = test_optimizer(instance, "cmaes", real_evals = 10L)
z = test_optimizer(instance, "cmaes", mu = 5, lambda = 5, real_evals = 10L)

expect_class(z$optimizer, "OptimizerBatchCmaes")
expect_snapshot(z$optimizer)

expect_error(test_optimizer_2d("cmaes", term_evals = 10L), "multi-crit objectives")
expect_error(test_optimizer_2d("cmaes", mu = 5, lambda = 5, term_evals = 10L), "multi-crit objectives")

instance$archive$clear()
optimizer = opt("cmaes", start_values = "custom", start = c(-9.1, 1.3))
optimizer = opt("cmaes", mu = 5, lambda = 5, start_values = "custom", start = c(-9.1, 1.3))
optimizer$optimize(instance)
# start values are used for the initial mean vector so a deterministic test is not applicable
})
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载