CMA-ES / pycma

Python implementation of CMA-ES
Other
1.1k stars 178 forks source link

Add custom stopping conditions #219

Closed AdrianPerezSalinas closed 1 year ago

AdrianPerezSalinas commented 1 year ago

Hi,

I was working with this package to solve a problem where the stopping criteria for optimizing one function depends on the value of another function. I want to add some custom criteria to stop the CMA strategy, but reading the documentation I could not find any satisfactory way of doing it.

Let me clarify what I am looking for with an example.

def f(x): 
    f = sum(x) # or some other function
    return f

def g(x): 
    g = sum(x**2) # or some other function
    return g

def callback(es): 
    x = es.best.x
    f_val = f(x)
    g_val = g(x)

    print(x, f_val, g_val)
    if g_val > 1: # or some other custom condition
        # stop optimization

x0 = np.random.rand(10)
sigma = 1

res = fmin(f, x0, sigma, callback=callback)

print(res)

Does the current version of CMA allows for this functionality or is it impossible?

Thank you in advance.

nikohansen commented 1 year ago

Yes, the option termination_callback is what you are looking for.

import cma
cma.CMAOptions('termination_call')
{'termination_callback': '[]  #v a function or list of functions returning True for termination, called in `stop` with `self` as argument, could be abused for side effects'}

It needs to return a value that evaluates to True to terminate the run.

def callback(es):
    return es.countiter > 5
x, es = cma.fmin2(f, x0, sigma, options={'termination_callback':callback})

terminates after five iterations via the callback function.

AdrianPerezSalinas commented 1 year ago

Thank you very much! This is exactly what I needed!