def runEA(self,nlay=None,type='GA',pop_size=100,max_evaluations=10000,**kwargs): import inspyred import random def mygenerate( random, args ): """ generate a random vector of model size """ return [random.random() for i in range( nlay*3 - 1 )] def my_observer(population, num_generations, num_evaluations, args): best = min(population) print('{0:6} -- {1}'.format(num_generations,best.fitness)) @inspyred.ec.evaluators.evaluator def datafit( individual, args ): misfit = (self.data-self.f.response(self.genMod(individual)))/self.error return np.mean(misfit**2) # prepare forward operator if self.f is None or (nlay is not None and nlay is not self.nlay): self.createFOP(nlay) lowerBound = pg.cat( pg.cat( pg.RVector(self.nlay-1,self.lowerBound[0]), pg.RVector(self.nlay,self.lowerBound[1])), pg.RVector(self.nlay,self.lowerBound[2]) ) upperBound = pg.cat( pg.cat( pg.RVector(self.nlay-1,self.upperBound[0]), pg.RVector(self.nlay,self.upperBound[1])), pg.RVector(self.nlay,self.upperBound[2]) ) if self.logpar: self.lLB, self.lUB = pg.log(lowerBound), pg.log(upperBound) # ready mapping functions else: self.lLB, self.lUB = lowerBound, upperBound # self.f = MRS1dBlockQTModelling(nlay, self.K, self.z, self.t) # setup random generator rand = random.Random() rand.seed(int(time.time())) # choose among different evolution algorithms if type == 'GA': ea = inspyred.ec.GA(rand) ea.variator = [inspyred.ec.variators.blend_crossover, inspyred.ec.variators.gaussian_mutation] ea.selector = inspyred.ec.selectors.tournament_selection ea.replacer = inspyred.ec.replacers.generational_replacement if type == 'SA': ea = inspyred.ec.SA(rand) if type == 'DEA': ea = inspyred.ec.DEA(rand) if type == 'PSO': ea = inspyred.swarm.PSO(rand) if type == 'ACS': ea = inspyred.swarm.ACS(rand,[]) if type == 'ES': ea = inspyred.ec.ES(rand) ea.terminator = [inspyred.ec.terminators.evaluation_termination, inspyred.ec.terminators.diversity_termination] else: ea.terminator = inspyred.ec.terminators.evaluation_termination #ea.observer = my_observer ea.observer = [inspyred.ec.observers.stats_observer, inspyred.ec.observers.file_observer] self.pop = ea.evolve(evaluator=datafit,generator=mygenerate,maximize=False, pop_size=pop_size,max_evaluations=max_evaluations,num_elites=1, bounder=inspyred.ec.Bounder(0.,1.),**kwargs) self.pop.sort(reverse=True) self.fits=[ind.fitness for ind in self.pop]
def runEMO(self,nlay=5,pop_size=100,max_generations=100): """ run evolutionary multi-objective optimization (EMO) using inspyred for now fixed to NSGA-II algorithm after Deb (2002) (non-dominated sorting genetic algorithm) """ import inspyred def genMods( individual ): """ generate MRS and VES models from unit vector """ model = pg.asvector( individual ) * ( self.lUB - self.lLB ) + self.lLB if self.logpar: model = pg.exp( model ) modMRS = model(0,nlay*3-1) modVES = pg.cat(model(0,nlay-1),model(nlay*3-1,nlay*4-1)) return modMRS, modVES def mygenerate( random, args ): """ generate a random vector of model size """ return [random.random() for i in range( nlay*4 - 1 )] @inspyred.ec.evaluators.evaluator def datafit( individual, args ): """ return data fits for MRS and VES as Pareto object """ modMRS, modVES = genMods(individual) MRSmisfit = ( self.data - self.f(modMRS) ) / self.error VESmisfit = ( np.log(self.rhoa) - np.log(self.fVES(modVES)) ) / np.log(1.02) return inspyred.ec.emo.Pareto([np.mean(MRSmisfit**2),np.mean(VESmisfit**2)]) self.createFOP(nlay) self.fVES = pg.DC1dModelling(nlay,self.ab2,self.mn2) lowerBound = pg.cat( pg.cat( pg.RVector(nlay-1,self.lowerBound[0]), pg.RVector(nlay,self.lowerBound[1])), pg.cat( pg.RVector(nlay,self.lowerBound[2]), pg.RVector(nlay,self.lowerBound[3]) ) ) upperBound = pg.cat( pg.cat( pg.RVector(nlay-1,self.upperBound[0]), pg.RVector(nlay,self.upperBound[1])), pg.cat( pg.RVector(nlay,self.upperBound[2]), pg.RVector(nlay,self.upperBound[3]) ) ) if self.logpar: self.lLB, self.lUB = pg.log(lowerBound), pg.log(upperBound) # ready mapping functions else: self.lLB, self.lUB = lowerBound, upperBound rand = random.Random() rand.seed(int(time.time())) ea = inspyred.ec.emo.NSGA2(rand) ea.variator = [inspyred.ec.variators.blend_crossover, inspyred.ec.variators.gaussian_mutation] ea.terminator = inspyred.ec.terminators.generation_termination ea.observer = [inspyred.ec.observers.stats_observer, inspyred.ec.observers.file_observer] self.pop = ea.evolve(evaluator=datafit, generator=mygenerate, maximize=False, bounder=inspyred.ec.Bounder(0.,1.), pop_size=pop_size, max_generations=max_generations)
import logging import pygimli as pg #log = logging.getLogger('pyGIMLi') #logging.basicConfig(level=logging.DEBUG, #format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', #datefmt='%m/%d/%Y %H:%M:%S', ##filename='example.log' #) pg.version() # test pygimli log pg.info("Start numeric log test." + str(pg.log(pg.RVector(1, 1.)))) pg.warn("Start warning test.") def testTraceback1(): def testTraceback2(): pg.error("Start error test.: int", 1, " vec", pg.RVector(2)) testTraceback2() testTraceback1() #pg.critical("Start critical test.") pg.debug("debug 0") pg.setDebug(1) pg.debug("debug ON") pg.setThreadCount(2)
import logging import pygimli as pg #log = logging.getLogger('pyGIMLi') #logging.basicConfig(level=logging.DEBUG, #format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', #datefmt='%m/%d/%Y %H:%M:%S', ##filename='example.log' #) pg.version() # test pygimli log pg.info("Start numeric log test." + str(pg.log(pg.RVector(1, 1.)))) pg.warn("Start warning test.") pg.error("Start error test.: int", 1, " vec", pg.RVector(2)) #pg.critical("Start critical test.") pg.debug("debug 0") pg.setDebug(1) pg.debug("debug ON") pg.setThreadCount(2) # should not printed out pg.setDebug(0) pg.debug("debug OFF") pg.setThreadCount(2) # test core log (should not be used outside the core)
def runEA(self, nlay=None, eatype='GA', pop_size=100, num_gen=100, runs=1, mp_num_cpus=8, **kwargs): """Run evolutionary algorithm using the inspyred library Parameters ---------- nlay : int [taken from classic fop if not given] number of layers pop_size : int [100] population size num_gen : int [100] number of generations runs : int [pop_size*num_gen] number of independent runs (with random population) eatype : string ['GA'] algorithm, choose among: 'GA' - Genetic Algorithm [default] 'SA' - Simulated Annealing 'DEA' - Discrete Evolutionary Algorithm 'PSO' - Particle Swarm Optimization 'ACS' - Ant Colony Strategy 'ES' - Evolutionary Strategy """ import inspyred import random def mygenerate(random, args): """generate a random vector of model size""" return [random.random() for i in range(nlay * 3 - 1)] def my_observer(population, num_generations, num_evaluations, args): """ print fitness over generation number """ best = min(population) print('{0:6} -- {1}'.format(num_generations, best.fitness)) @inspyred.ec.evaluators.evaluator def datafit(individual, args): """ error-weighted data misfit as basis for evaluating fitness """ misfit = (self.data - self.fop.response(self.genMod(individual))) / self.error return np.mean(misfit**2) # prepare forward operator if self.fop is None or (nlay is not None and nlay is not self.nlay): self.fop = MRS.createFOP(nlay) lowerBound = pg.cat( pg.cat(pg.RVector(self.nlay - 1, self.lowerBound[0]), pg.RVector(self.nlay, self.lowerBound[1])), pg.RVector(self.nlay, self.lowerBound[2])) upperBound = pg.cat( pg.cat(pg.RVector(self.nlay - 1, self.upperBound[0]), pg.RVector(self.nlay, self.upperBound[1])), pg.RVector(self.nlay, self.upperBound[2])) if self.logpar: self.lLB, self.lUB = pg.log(lowerBound), pg.log( upperBound) # ready mapping functions else: self.lLB, self.lUB = lowerBound, upperBound # self.f = MRS1dBlockQTModelling(nlay, self.K, self.z, self.t) # setup random generator rand = random.Random() # choose among different evolution algorithms if eatype == 'GA': ea = inspyred.ec.GA(rand) ea.variator = [ inspyred.ec.variators.blend_crossover, inspyred.ec.variators.gaussian_mutation ] ea.selector = inspyred.ec.selectors.tournament_selection ea.replacer = inspyred.ec.replacers.generational_replacement if eatype == 'SA': ea = inspyred.ec.SA(rand) if eatype == 'DEA': ea = inspyred.ec.DEA(rand) if eatype == 'PSO': ea = inspyred.swarm.PSO(rand) if eatype == 'ACS': ea = inspyred.swarm.ACS(rand, []) if eatype == 'ES': ea = inspyred.ec.ES(rand) ea.terminator = [ inspyred.ec.terminators.evaluation_termination, inspyred.ec.terminators.diversity_termination ] else: ea.terminator = inspyred.ec.terminators.evaluation_termination # ea.observer = my_observer ea.observer = [ inspyred.ec.observers.stats_observer, inspyred.ec.observers.file_observer ] tstr = '{0}'.format(time.strftime('%y%m%d-%H%M%S')) self.EAstatfile = self.basename + '-' + eatype + 'stat' + tstr + '.csv' with open(self.EAstatfile, 'w') as fid: self.pop = [] for i in range(runs): rand.seed(int(time.time())) self.pop.extend( ea.evolve(evaluator=datafit, generator=mygenerate, maximize=False, pop_size=pop_size, max_evaluations=pop_size * num_gen, bounder=inspyred.ec.Bounder(0., 1.), num_elites=1, statistics_file=fid, **kwargs)) # self.pop.extend(ea.evolve( # generator=mygenerate, maximize=False, # evaluator=inspyred.ec.evaluators.parallel_evaluation_mp, # mp_evaluator=datafit, mp_num_cpus=mp_num_cpus, # pop_size=pop_size, max_evaluations=pop_size*num_gen, # bounder=inspyred.ec.Bounder(0., 1.), num_elites=1, # statistics_file=fid, **kwargs)) self.pop.sort(reverse=True) self.fits = [ind.fitness for ind in self.pop] print('minimum fitness of ' + str(min(self.fits)))
def invert(self, data, values=None, verbose=0, **kwargs): """ Invert the given data. A parametric mesh for the inversion will be created if non is given before. Parameters ---------- """ self.fop.setVerbose(verbose) self.inv.setVerbose(verbose) self.inv.setMaxIter(kwargs.pop('maxiter', 10)) self.inv.setLambda(kwargs.pop('lambd', 10)) if self.paraMesh is None: self.paraMesh = createParaMesh2dGrid(data.sensorPositions(), **kwargs) self.setParaMesh(self.paraMesh) if verbose: print(self.paraMesh) # pg.show(self.paraMesh) err = data('err') rhoa = data('rhoa') startModel = pg.RVector(self.fop.regionManager().parameterCount(), pg.median(rhoa)) self.fop.setData(data) self.inv.setForwardOperator(self.fop) # check err here self.inv.setData(rhoa) self.inv.setError(err) self.inv.setModel(startModel) model = self.inv.run() if values is not None: if isinstance(values, pg.RVector): values = [values] elif isinstance(values, np.ndarray): if values.ndim == 1: values = [values] allModel = pg.RMatrix(len(values), len(model)) self.inv.setVerbose(False) for i in range(len(values)): print(i) tic = time.time() self.inv.setModel(model) self.inv.setReferenceModel(model) dData = pg.abs(values[i] / rhoa) relModel = self.inv.invSubStep(pg.log(dData)) allModel[i] = model * pg.exp(relModel) print(i, "/", len(values), " : ", time.time()-tic, "s min/max: ", min(allModel[i]), max(allModel[i])) return allModel return model
def invert(self, data, values=None, verbose=0, **kwargs): """ Invert the given data. A parametric mesh for the inversion will be created if non is given before. Parameters ---------- """ self.fop.setVerbose(verbose) self.inv.setVerbose(verbose) self.inv.setMaxIter(kwargs.pop('maxiter', 10)) self.inv.setLambda(kwargs.pop('lambd', 10)) if self.paraMesh is None: self.paraMesh = createParaMesh2dGrid(data.sensorPositions(), **kwargs) self.setParaMesh(self.paraMesh) if verbose: print(self.paraMesh) # pg.show(self.paraMesh) err = data('err') rhoa = data('rhoa') startModel = pg.RVector(self.fop.regionManager().parameterCount(), pg.median(rhoa)) self.fop.setData(data) self.inv.setForwardOperator(self.fop) # check err here self.inv.setData(rhoa) self.inv.setError(err) self.inv.setModel(startModel) model = self.inv.run() if values is not None: if isinstance(values, pg.RVector): values = [values] elif isinstance(values, np.ndarray): if values.ndim == 1: values = [values] allModel = pg.RMatrix(len(values), len(model)) self.inv.setVerbose(False) for i in range(len(values)): print(i) tic = time.time() self.inv.setModel(model) self.inv.setReferenceModel(model) dData = pg.abs(values[i] / rhoa) relModel = self.inv.invSubStep(pg.log(dData)) allModel[i] = model * pg.exp(relModel) print(i, "/", len(values), " : ", time.time() - tic, "s min/max: ", min(allModel[i]), max(allModel[i])) return allModel return model
import logging import pygimli as pg log = logging.getLogger('pyGIMLi') logging.basicConfig( level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt='%m/%d/%Y %H:%M:%S', #filename='example.log' ) log.info("Start test.") log.warn("Start test.") log.debug("Start test.") log.error("Start test.") log.critical("Start test.") # test core log pg.setThreadCount(2) pg.log(pg.Debug, "core log ") log.exception("Exception")
def runEA(self, nlay=None, eatype='GA', pop_size=100, num_gen=100, runs=1, mp_num_cpus=8, **kwargs): """ Run evolutionary algorithm using inspyred library Parameters ---------- nlay : int - number of layers\n pop_size : int - population size\n num_gen : int - number of generations\n runs : int - number of independent runs (with random population)\n eatype : string - algorithm, choose among:\n 'GA' - Genetic Algorithm [default]\n 'SA' - Simulated Annealing\n 'DEA' - Discrete Evolutionary Algorithm\n 'PSO' - Particle Swarm Optimization\n 'ACS' - Ant Colony Strategy\n 'ES' - Evolutionary Strategy """ import inspyred import random def mygenerate(random, args): """generate a random vector of model size""" return [random.random() for i in range(nlay * 3 - 1)] def my_observer(population, num_generations, num_evaluations, args): """ print fitness over generation number """ best = min(population) print('{0:6} -- {1}'.format(num_generations, best.fitness)) @inspyred.ec.evaluators.evaluator def datafit(individual, args): """ error-weighted data misfit as basis for evaluating fitness """ misfit = (self.data - self.f.response(self.genMod(individual))) / \ self.error return np.mean(misfit**2) # prepare forward operator if self.f is None or (nlay is not None and nlay is not self.nlay): self.createFOP(nlay) lowerBound = pg.cat(pg.cat(pg.RVector(self.nlay - 1, self.lowerBound[0]), pg.RVector(self.nlay, self.lowerBound[1])), pg.RVector(self.nlay, self.lowerBound[2])) upperBound = pg.cat(pg.cat(pg.RVector(self.nlay - 1, self.upperBound[0]), pg.RVector(self.nlay, self.upperBound[1])), pg.RVector(self.nlay, self.upperBound[2])) if self.logpar: self.lLB, self.lUB = pg.log(lowerBound), pg.log( upperBound) # ready mapping functions else: self.lLB, self.lUB = lowerBound, upperBound # self.f = MRS1dBlockQTModelling(nlay, self.K, self.z, self.t) # setup random generator rand = random.Random() # choose among different evolution algorithms if eatype == 'GA': ea = inspyred.ec.GA(rand) ea.variator = [ inspyred.ec.variators.blend_crossover, inspyred.ec.variators.gaussian_mutation] ea.selector = inspyred.ec.selectors.tournament_selection ea.replacer = inspyred.ec.replacers.generational_replacement if eatype == 'SA': ea = inspyred.ec.SA(rand) if eatype == 'DEA': ea = inspyred.ec.DEA(rand) if eatype == 'PSO': ea = inspyred.swarm.PSO(rand) if eatype == 'ACS': ea = inspyred.swarm.ACS(rand, []) if eatype == 'ES': ea = inspyred.ec.ES(rand) ea.terminator = [inspyred.ec.terminators.evaluation_termination, inspyred.ec.terminators.diversity_termination] else: ea.terminator = inspyred.ec.terminators.evaluation_termination # ea.observer = my_observer ea.observer = [ inspyred.ec.observers.stats_observer, inspyred.ec.observers.file_observer] tstr = '{0}'.format(time.strftime('%y%m%d-%H%M%S')) self.EAstatfile = self.basename + '-' + eatype + 'stat' + tstr + '.csv' with open(self.EAstatfile, 'w') as fid: self.pop = [] for i in range(runs): rand.seed(int(time.time())) self.pop.extend(ea.evolve( evaluator=datafit, generator=mygenerate, maximize=False, pop_size=pop_size, max_evaluations=pop_size*num_gen, bounder=inspyred.ec.Bounder(0., 1.), num_elites=1, statistics_file=fid, **kwargs)) # self.pop.extend(ea.evolve( # generator=mygenerate, maximize=False, # evaluator=inspyred.ec.evaluators.parallel_evaluation_mp, # mp_evaluator=datafit, mp_num_cpus=mp_num_cpus, # pop_size=pop_size, max_evaluations=pop_size*num_gen, # bounder=inspyred.ec.Bounder(0., 1.), num_elites=1, # statistics_file=fid, **kwargs)) self.pop.sort(reverse=True) self.fits = [ind.fitness for ind in self.pop] print('minimum fitness of ' + str(min(self.fits)))
def runEMO(self, nlay=5, pop_size=100, max_generations=100): """ Run evolutionary multi-objective optimization (EMO) Run EMO using inspyred for now fixed to NSGA-II algorithm after Deb (2002) TODO (cite correctly) (non-dominated sorting genetic algorithm) """ import inspyred def genMods(individual): """generate MRS and VES models from unit vector""" model = individual * (self.lUB - self.lLB) + self.lLB # model = pg.asvector(individual) * (self.lUB - self.lLB) + self.lLB if self.logpar: model = pg.exp(model) modMRS = model(0, nlay * 3 - 1) modVES = pg.cat(model(0, nlay - 1), model(nlay * 3 - 1, nlay * 4 - 1)) return modMRS, modVES def mygenerate(random, args): """generate a random vector of model size""" return [random.random() for i in range(nlay * 4 - 1)] @inspyred.ec.evaluators.evaluator def datafit(individual, args): """return data fits for MRS and VES as Pareto object""" modMRS, modVES = genMods(individual) MRSmisfit = (self.data - self.f(modMRS)) / self.error VESmisfit = (np.log(self.rhoa) - np.log(self.fVES(modVES))) / np.log(1.02) return inspyred.ec.emo.Pareto( [np.mean(MRSmisfit**2), np.mean(VESmisfit**2)]) self.createFOP(nlay) self.fVES = pg.DC1dModelling(nlay, self.ab2, self.mn2) lowerBound = pg.cat( pg.cat(pg.RVector(nlay - 1, self.lowerBound[0]), pg.RVector(nlay, self.lowerBound[1])), pg.cat(pg.RVector(nlay, self.lowerBound[2]), pg.RVector(nlay, self.lowerBound[3]))) upperBound = pg.cat( pg.cat(pg.RVector(nlay - 1, self.upperBound[0]), pg.RVector(nlay, self.upperBound[1])), pg.cat(pg.RVector(nlay, self.upperBound[2]), pg.RVector(nlay, self.upperBound[3]))) if self.logpar: self.lLB, self.lUB = pg.log(lowerBound), pg.log( upperBound) # ready mapping functions else: self.lLB, self.lUB = lowerBound, upperBound rand = random.Random() rand.seed(int(time.time())) ea = inspyred.ec.emo.NSGA2(rand) ea.variator = [ inspyred.ec.variators.blend_crossover, inspyred.ec.variators.gaussian_mutation ] ea.terminator = inspyred.ec.terminators.generation_termination ea.observer = [ inspyred.ec.observers.stats_observer, inspyred.ec.observers.file_observer ] self.pop = ea.evolve(evaluator=datafit, generator=mygenerate, maximize=False, bounder=inspyred.ec.Bounder(0., 1.), pop_size=pop_size, max_generations=max_generations)