-
Notifications
You must be signed in to change notification settings - Fork 79
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
"Matching" libcmaes results with cma_es in R #193
Comments
I think that it may be possible that the R implementation of CMA-ES may be using a different constraint handling method than libcmaes? I'm not quite certain, but it seems plausible that cma_es in R is using a penalty function and libcmaes is using a decoder function (mapping genotypes to phenotypes)? |
Hi, very possible indeed. See the 'boundary and constraint handling' section of http://cma.gforge.inria.fr/cmaes_sourcecode_page.html#testing libcmaes uses a piecewise quadraric function. See https://github.com/beniz/libcmaes/blob/master/src/pwq_bound_strategy.cc |
this is likely to be a bad way to handle bound constraints. This section gives a quick overview of possible ways how to handle bounds.
This must be considered as a failure of the algorithm. As a simple first step, check what happens if the lower bounds are set to -10.
AFAICS, it would certainly not be desirable to replication the results from the |
Dr. Hansen, you are in fact the next person I was going to contact regarding these issues. Based on the commit history in libcmaes, it seems you have helped contribute to this library, and you are also responsible for pycma (not to mention the algorithm itself). I was trying to get to the bottom of this while admittedly trying to avoid the need to completely understand all of the subtleties of the algorithm, as I am simply translating an R script that employs the algorithm into C++11 to increase performance. I ran an example of pycma with the sphere as the fitness function and got results consistent with libcmaes:
which results in the output:
which is clearly similar to libcmaes. Dr. Benazera was kind enough to respond previously with a link that I believe is hosted by you, in which various implementations of CMA-ES across many languages are listed. The R library cmaes is among them. It appears it was written by Olaf Mersmann and David Arnu. Did you assist them in any way? Since the sphere is a standard test objective function, the fact that the algorithm is failing (note that it fails with the same results whether I write the objective function myself or employ I also used your suggestion and changed the lower bounds to -10. The results from doing so with libcmaes and pycma are consistent, but they are not with cmaes in R. There are no longer any constraint violations in the R output message, but the parameter values (as well as the corresponding fitness function value) are so incredibly small as to amount to zero, with a stop condition message that "All standard deviations smaller than tolerance." The results for each with the new bounds are below: libcmaes:
pycma:
cmaes in R:
So I suppose the question becomes, is there something inherently wrong with the R libraries implementation of CMA-ES? I appreciate both of your input and I apologize in advance if any of my questions are the result of my naive understanding of the algorithm. As an aside, I am noticing that when I lower the stopping tolerance in pycma (i.e. 'tolfun') from 0.5e-12 to say 0.5e-3 the algorithm converges more quickly, but with libcmaes doing the same (using |
No, but I would give them the credit to be able to implement CMA-ES.
As the experiment I have seen was to my understanding on the bounded sphere, all could be caused by a way too naive boundary handling.
Handling of bound constraints is not part of "standard" CMA-ES.
That looks reasonably fine. It just means that not the same termination conditions are applied.
As written above: to answer this question we need much more comprehensive experimentation and output. To find that it works on the sphere function is certainly not sufficient.
I am pretty sure your interpretation is wrong. The algorithm terminates earlier, but it has also achieve lesser precision. That makes perfectly sense. I strongly suggest to use the
My hunch is that the new parameter setting was ignored. BTW, I believe you can use |
Dr. Hansen, many thanks for the thorough response. As I originally stated, the end goal for me here is to be able to replicate the results being produced with cmaes in R with libcmaes. You mentioned in your last response that:
in regards to the optimization results coming from the R script (which do not match the very similar results produced with libcmaes and pycma). I have found that I can produce the same results with cmaes in R by changing the stopping tolerance "stop.tolx" to a much larger value than 0.5e-12. The issue I am having now is regarding changing the tolerances in libcmaes. There are obviously multiple different avenues for halting the algorithm. With pycma I am changing three values to ensure that the results are consistent with cmaes in R:
Where tolfun and tolfunhist were set arbitrarily small to ensure that termination is triggered by tolx. When I do this, the algorithm terminates in the range of where I want it to (i.e. it is in the range of the results in R that I am trying to match). I am having trouble doing the same with libcmaes. I see in the API that there are two CMAParameters member functions that should achieve the same as within pycma: cmaparams.set_xtolerance(1.4e-20); // sets parameter tolerance as stopping criteria for TolX I cannot seem to find the equivalent member function corresponding to 'tolfun' in pycma. This is a problem right now because as I mentioned previously dropping the xtolerance is not having any effect, and that is likely due another stopping criteria being met first (I suspect it may be the equivalent to tolfun). The nice thing about pycma is that the output is telling you which stopping criteria triggered the algorithm to stop. That might be a useful addition to libcmaes (if it doesn't already exist). If I can set the other criteria arbitrarily low so as to allow a much smaller xtol to trigger the stop, I think I can finally match the R cmaes results that I am trying to translate into C++. Thanks again for your assistance! |
I can't speak to the Or in other words, the results you are trying to match are specific to the situation that the optimum is in zero. |
On that note, the last question I have is in regards to the stopping criteria in libcmaes. I can't quite grasp what is causing the algorithm to terminate when I set both the xtolerance and ftolerance anywhere in the range of 1e-12 to zero. When doing that I get the following values for the sphere:
I tried going through each of the stopping criteria and setting them equal to false and the only thing that had any effect was setting TOLHISTFUN to false:
When I do that I get:
The reason I ask is because the stopping tolerances seem to be handled differently in the R library and the xtolerance that I am trying to match in R halts the algorithm with values in the range of:
and I can't seem to achieve the same here because apparently something other than the xtolerance is causing the algorithm to halt. |
I am not sure what the question is. As you found out the |
I am trying to translate an R script into C++ that employs the cmaes library:
https://www.rdocumentation.org/packages/cmaes/versions/1.0-11/topics/cma_es
https://github.com/cran/cmaes/blob/master/R/cmaes.R
I am a novice with this algorithm and was hoping I might be able to get some helpful tips/advice. I am using libcmaes and trying to validate the results produced in R (to the extent that they can be validated, since RNG's across languages using the same seed will still produce different numbers, despite using the same generator). I am using the 2d sphere as the fitness function. The R script that I am trying to replicate with libcmaes is rather straightforward and shown below:
It appears from the print statements that the vast majority of the fitness function evaluations result in constraint violations (5596 of 5688), and the parameters seem to default to either the lower or upper bounds when this occurs. In addition, by the final iteration sigma has grown to be extremely large (2.424594e+154). The best set of parameters (0.1922440, 0.1913787, 1.5348315, 1.5386994, 0.3485390) correspond to the 155th evaluation, and the value of the fitness function corresponding to these parameters is 4.918367.
The corresponding implementation using libcmaes is below:
Here sigma, lambda, the maximum number of iterations, and the stopping tolerance are set to the defaults used in R (they may be redundant if they happen to be the same by default in libcmaes). The seed number and bounds match those chosen in the R script. The output is below:
best solution => f-value=3.00969e-19 / fevals=944 / sigma=0.000234238 / iter=118 / elaps=7ms / x=3.02083e-11 4.24404e-10 1.94338e-10 1.07636e-13 2.86654e-10
Here the function value, sigma, and the optimal parameters are all very small when compared to the results in R. However, when I use
cmaparams.set_ftarget(4.918367)
to set the target value to the result found in R, I get results in the ballpark of what was found there. It seems clear to me that the issue seems to be with how the bounds are implemented in the R version of CMA-ES (in which the constraints are allowed to be violated). I was hoping to get some clarification on whether or not there is something in libcmaes that I am missing that would assist me in "replicating" (to the extent that they can be replicated) the results determined in R.The text was updated successfully, but these errors were encountered: