-
-
Notifications
You must be signed in to change notification settings - Fork 5.1k
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
TNC does not return optimal parameters #12111
Comments
Case that demonstrates:
gives
|
In the case of TNC there is a big discrepancy. It's obviously a long way from the minimum ( If, however, there is a stale value not being updated in a loop somewhere, then that's a more serious issue. One possible solution in this situation is to add |
Hi @andyfaff , thanks for creating the case demonstration. This seems to be the exact problem. I agree that just caching the best solution inside Since we did not observe this behavior for any other optimizers (we had one possible case with L-BFGS, but I cannot reproduce that, so I'm not sure), it might be specific to TNC and there indeed a weird behavior of the algorithm, or a bug, as you point out. |
So lets have a look at all the minimizers:
gives
You'll see that the minimisation with TNC does not result in Now let's revisit the minimum function value being visited by the objective. Imagine a solver whose mode of operation is What would be a bug would be the optimizer halting based on the process I've just described, but with the As such, I don't think the OP is evidence for an actual bug in the solvers. |
Hi, thanks for the profound analysis.
Yes, we did not check
I see your point about FD. Since we provided analytic gradients (which you did not for all optimizers above), I suspect far less optimizers showed this behavior than above, except some which evaluated points which were then not used to update the trace history, like, potentially, TNC. I agree that returning fval2 is the "right thing to do" from the search algorithm perspective. If one is just interested in overall best parameter values, it is of course always possible to manually self-record them, as in
Agreed. It was striking that TNC showed this behavior quite often compared to the others (providing gradients), and seems to always return the last evaluated function value, not the best, the difference being beyond any tolerance threshold. Whether this is a flaw of the algorithm (corresponding to returning |
Here's for completion an illustration of how only TNC fails in gradient-based mode: import numpy as np
from scipy.optimize import rosen, minimize, rosen_der, rosen_hess
class F():
def __init__(self):
self.best_fun = np.inf
self.best_x = None
def __call__(self, x):
fun = rosen(x)
if fun < self.best_fun:
self.best_fun = fun
self.best_x = x
return fun
meths = ['nelder-mead', 'cg', 'bfgs', 'l-bfgs-b', 'tnc', 'cobyla', 'slsqp', 'trust-constr',
'dogleg', 'trust-ncg', 'trust-exact', 'trust-krylov']
for method in meths:
jac = hess = None
#if method in ('newton-cg', 'trust-krylov', 'trust-exact',
# 'trust-ncg', 'dogleg'):
jac = rosen_der
#if method in ('trust-krylov', 'trust-exact', 'trust-ncg',
# 'dogleg'):
hess = rosen_hess
x0 = [-0.16584467, 1.31897148, -3.26098005, 3.45927947, 0.29453825,
1.31031958, -1.75957634, -1.83706183, 3.42357846, -0.78687309]
f = F()
res = minimize(f, x0, method=method, jac=jac, hess=hess, options={'maxiter': 100})
print(method, np.equal(res.fun, f.best_fun), res.fun, f.best_fun, res.success, res.message) gives
Indeed, setting |
Closing because I think the following is True:
Note that some of the examples had Furthermore, there is an issue when using TNC with a callback function, the callback mechanism in the TNC code was mutating the output. This is being fixed in #14882. |
The truncated Newton (TNC) optimizer
scipy.optimize.minimize(method='TNC')
returns apparently not the optimal parameter vector and function value, but the last one, which often (depending on the dimension of the problem in 10-30% of cases in our applications) has a higher function value.Expected behavior: It should return the optimal found parameters and function value.
This behavior was not observed for any other scipy optimizer considered.
Reproducing code example:
We encountered this problem in our parameter estimation tool github.com/icb-dcm/pypesto, which employs an objective function which records a history of all function evaluations and can thus report if the best value in the trace is better than the value reported by the optimizer. See here for a discussion: ICB-DCM/pyPESTO#327. The error can be reproduced in cell 5 of the notebook https://github.com/ICB-DCM/pyPESTO/blob/master/doc/example/rosenbrock.ipynb. The problem only has box constraints, which are not violated.
Error message:
Scipy/Numpy/Python version information:
The text was updated successfully, but these errors were encountered: