I believe it is a trivial question but I was not able to find any example and I am struggling to understand how to use this instruction for creating a callback for scipy.optimize
import scipy.optimize as sp
res = sp.minimize(FUN, 0.25,method='Nelder-Mead',bounds=None,callback=STOP)
where the callback is defined as:
def STOP(intermediate_result: sp.OptimizeResult):
print('intermediate_results',intermediate_result)
if intermediate_result.fun < 0.005:
return StopIteration
else:
return 0
The intermediate_result
appears to be only the optimal parameter (so it seems I am implemented the instruction callback(xk) and not callback(intermediate_result: OptimizeResult) )
I would like that my function STOP analyse the value of the returned function value and stop in case the value is smaller than 0.005
But generally I would like to understand what the guidance is saying:
All methods except TNC, SLSQP, and COBYLA support a callable with the signature:
callback(intermediate_result: OptimizeResult)
where intermediate_result is a keyword parameter containing an OptimizeResult with attributes x and fun, the present values of the parameter vector and objective function.
Could you please help me ?
When I tried that I got:
AttributeError: 'numpy.ndarray' object has no attribute 'fun'
I tried different way to change the keyword in the function and inside the optimizer but I have not clue of what I am doing
In previous version of SciPy the callback parameter was the current x
value as a nd.array
(<= 1.9.3). In newer version it is a partial OptimizeResult
with fun
and x
(1.12.0).
First upgrade to latest version of SciPy, then try this MCVE
from scipy import optimize
def callback(intermediate_result):
if intermediate_result.fun < 0.5:
raise StopIteration
optimize.minimize(optimize.rosen, x0=[0, 0, 0, 0], method='Nelder-Mead', tol=1e-6, callback=callback)
Also notice that exception should be raise
d not return
ed.
For older versions, you have to compute the solution by yourself and raising StopIetration
will stop the script (so you have to catch it):
def callback(intermediate_result):
if optimize.rosen(intermediate_result) < 0.5:
raise StopIteration
Where new version will stop the algorithm and return a solution with corresponding message:
# message: `callback` raised `StopIteration`.
# success: False
# status: 99
# fun: 0.4281196937835328
To update your WSL to the latest scipy, issue the following command:
python -m pip install -U --user scipy