Closed ivarbratberg closed 3 months ago
The _copy_light
method seems to be what you are looking for.
import cma
cma.CMAEvolutionStrategy._copy_light??
Signature: cma.CMA._copy_light(self, sigma=None, inopts=None)
Source:
def _copy_light(self, sigma=None, inopts=None):
"""tentative copy of self, versatile (interface and functionalities may change).
`sigma` overwrites the original initial `sigma`.
`inopts` allows to overwrite any of the original options.
This copy may not work as expected depending on the used sampler.
Copy mean and sample distribution parameters and input options. Do
not copy evolution paths, termination status or other state variables.
>>> import cma
>>> es = cma.CMAEvolutionStrategy(3 * [1], 0.1,
... {'bounds':[0,9], 'verbose':-9}).optimize(cma.ff.elli, iterations=10)
>>> es2 = es._copy_light()
>>> assert es2.sigma == es.sigma
>>> assert sum((es.sm.C - es2.sm.C).flat < 1e-12)
>>> es3 = es._copy_light(sigma=3)
>>> assert es3.sigma == es3.sigma0 == 3
>>> es.mean[0] = -11
>>> es4 = es._copy_light(inopts={'CMA_on': False})
>>> assert es4.sp.c1 == es4.sp.cmu == 0
>>> assert es.mean[0] == -11 and es4.mean[0] >= -4.5
"""
if sigma is None:
sigma = self.sigma
opts = dict(self.inopts)
if inopts is not None:
opts.update(inopts)
es = type(self)(self.gp.pheno(self.mean[:], into_bounds=self.boundary_handler.repair),
sigma, opts)
es.sigma_vec = transformations.DiagonalDecoding(self.sigma_vec.scaling)
try: es.sm.C = self.sm.C.copy()
except: warnings.warn("self.sm.C.copy failed")
es.sm.update_now(-1) # make B and D consistent with C
es._updateBDfromSM()
return es
In case you use the functional interface: the second return argument of cma.fmin2
is the cma.CMAEvolutionStrategy
class instance to be used and the second argument to fmin2
can be the light-copied class instance.
You may also just directly use these few lines given es
is the previous class instance:
es2 = cma.CMAEvolutionStrategy(...)
es2.sigma_vec = cma.transformations.DiagonalDecoding(es.sigma_vec.scaling)
es2.sm.C = es.sm.C.copy()
es2.sm.update_now(-1) # make B and D consistent with C
es2._updateBDfromSM()
It seems like a good idea if this would work (it doesn't currently) by executing the above lines:
es2 = cma.CMAEvolutionStrategy(...)
es2._set_C_from(es)
EDIT: this works now with the current code.
Great thank you , I will check this out and give feedback.
Using this class would allow the above two liner to work [update: works now without the below class]:
class CMAEvolutionStrategyWithSetCovarianceFrom(cma.CMAEvolutionStrategy):
def _set_C_from(self, es):
"""set the current covariance matrix from another class instance.
This may not work as expected unless the default sampler is used.
"""
if es.N != self.N:
warnings.warn("setting C with dimension {} != {} (the current "
"dimension). This is likely to fail."
.format(es.N, self.N))
self.sigma_vec = transformations.DiagonalDecoding(es.sigma_vec.scaling)
try:
self.sm.C = es.sm.C.copy()
except Exception:
warnings.warn("es.sm.C.copy() failed")
self.sm.update_now(-1) # make B and D consistent with C
self._updateBDfromSM()
Ok thanks!
Can this be closed?
Yes, thank you a lot for your help. I have tested it out, and it works as expected, albeit for many cases I work with it seems like starting with previous found best optimum point and diagonal covariance matrix gives just as good progress
@nikohansen any way to also copy the evolution paths? I think in the OP's use-case it would be useful to continue training with a checkpoint of the last evolution paths.
Evolution paths can be found in the attributes ps
, pc
and pc2
.
Hi, the context is the following. I have optimized the system already. Then the system has changed slightly and I would like to optimize again
In this context, it would be nice not only to provide the initial values where to start the search and the sigma, but also the covariance matrix.
Would it be possible to provide a initial covariance parameter ?