Spaces:
Running
Running
Commit
·
35b5720
1
Parent(s):
c2c1511
Introduce perturbation factor
Browse files- eureqa.jl +10 -21
- eureqa.py +6 -1
- hyperparamopt.py +5 -4
eureqa.jl
CHANGED
|
@@ -208,7 +208,7 @@ function mutateConstant(
|
|
| 208 |
end
|
| 209 |
|
| 210 |
bottom = 0.1f0
|
| 211 |
-
maxChange = T + 1.0f0 + bottom
|
| 212 |
factor = maxChange^Float32(rand())
|
| 213 |
makeConstBigger = rand() > 0.5
|
| 214 |
|
|
@@ -490,10 +490,7 @@ end
|
|
| 490 |
|
| 491 |
# Go through one simulated annealing mutation cycle
|
| 492 |
# exp(-delta/T) defines probability of accepting a change
|
| 493 |
-
function iterate(
|
| 494 |
-
tree::Node, T::Float32;
|
| 495 |
-
annealing::Bool=true
|
| 496 |
-
)::Node
|
| 497 |
prev = tree
|
| 498 |
tree = copyNode(tree)
|
| 499 |
|
|
@@ -592,13 +589,9 @@ function bestSubPop(pop::Population; topn::Integer=10)::Population
|
|
| 592 |
end
|
| 593 |
|
| 594 |
# Mutate the best sampled member of the population
|
| 595 |
-
function iterateSample(
|
| 596 |
-
pop::Population, T::Float32;
|
| 597 |
-
annealing::Bool=true)::PopMember
|
| 598 |
allstar = bestOfSample(pop)
|
| 599 |
-
new = iterate(
|
| 600 |
-
allstar.tree, T,
|
| 601 |
-
annealing=annealing)
|
| 602 |
allstar.tree = new
|
| 603 |
allstar.score = scoreFunc(new)
|
| 604 |
allstar.birth = getTime()
|
|
@@ -607,11 +600,9 @@ end
|
|
| 607 |
|
| 608 |
# Pass through the population several times, replacing the oldest
|
| 609 |
# with the fittest of a small subsample
|
| 610 |
-
function regEvolCycle(
|
| 611 |
-
pop::Population, T::Float32;
|
| 612 |
-
annealing::Bool=true)::Population
|
| 613 |
for i=1:round(Integer, pop.n/ns)
|
| 614 |
-
baby = iterateSample(pop, T
|
| 615 |
#printTree(baby.tree)
|
| 616 |
oldest = argmin([pop.members[member].birth for member=1:pop.n])
|
| 617 |
pop.members[oldest] = baby
|
|
@@ -623,17 +614,16 @@ end
|
|
| 623 |
# printing the fittest equation every 10% through
|
| 624 |
function run(
|
| 625 |
pop::Population,
|
| 626 |
-
ncycles::Integer
|
| 627 |
-
annealing::Bool=false;
|
| 628 |
verbosity::Integer=0
|
| 629 |
)::Population
|
| 630 |
|
| 631 |
allT = LinRange(1.0f0, 0.0f0, ncycles)
|
| 632 |
for iT in 1:size(allT)[1]
|
| 633 |
if annealing
|
| 634 |
-
pop = regEvolCycle(pop, allT[iT]
|
| 635 |
else
|
| 636 |
-
pop = regEvolCycle(pop, 1.0f0
|
| 637 |
end
|
| 638 |
|
| 639 |
if verbosity > 0 && (iT % verbosity == 0)
|
|
@@ -721,7 +711,6 @@ end
|
|
| 721 |
|
| 722 |
function fullRun(niterations::Integer;
|
| 723 |
npop::Integer=300,
|
| 724 |
-
annealing::Bool=true,
|
| 725 |
ncyclesperiteration::Integer=3000,
|
| 726 |
fractionReplaced::Float32=0.1f0,
|
| 727 |
verbosity::Integer=0,
|
|
@@ -738,7 +727,7 @@ function fullRun(niterations::Integer;
|
|
| 738 |
for k=1:niterations
|
| 739 |
# Spawn threads to run indepdent evolutions, then gather them
|
| 740 |
@inbounds Threads.@threads for i=1:nthreads
|
| 741 |
-
allPops[i] = run(allPops[i], ncyclesperiteration,
|
| 742 |
bestSubPops[i] = bestSubPop(allPops[i], topn=topn)
|
| 743 |
for j=1:bestSubPops[i].n
|
| 744 |
bestSubPops[i].members[j].tree = simplifyTree(bestSubPops[i].members[j].tree)
|
|
|
|
| 208 |
end
|
| 209 |
|
| 210 |
bottom = 0.1f0
|
| 211 |
+
maxChange = perturbationFactor * T + 1.0f0 + bottom
|
| 212 |
factor = maxChange^Float32(rand())
|
| 213 |
makeConstBigger = rand() > 0.5
|
| 214 |
|
|
|
|
| 490 |
|
| 491 |
# Go through one simulated annealing mutation cycle
|
| 492 |
# exp(-delta/T) defines probability of accepting a change
|
| 493 |
+
function iterate(tree::Node, T::Float32)::Node
|
|
|
|
|
|
|
|
|
|
| 494 |
prev = tree
|
| 495 |
tree = copyNode(tree)
|
| 496 |
|
|
|
|
| 589 |
end
|
| 590 |
|
| 591 |
# Mutate the best sampled member of the population
|
| 592 |
+
function iterateSample(pop::Population, T::Float32)::PopMember
|
|
|
|
|
|
|
| 593 |
allstar = bestOfSample(pop)
|
| 594 |
+
new = iterate(allstar.tree, T)
|
|
|
|
|
|
|
| 595 |
allstar.tree = new
|
| 596 |
allstar.score = scoreFunc(new)
|
| 597 |
allstar.birth = getTime()
|
|
|
|
| 600 |
|
| 601 |
# Pass through the population several times, replacing the oldest
|
| 602 |
# with the fittest of a small subsample
|
| 603 |
+
function regEvolCycle(pop::Population, T::Float32)::Population
|
|
|
|
|
|
|
| 604 |
for i=1:round(Integer, pop.n/ns)
|
| 605 |
+
baby = iterateSample(pop, T)
|
| 606 |
#printTree(baby.tree)
|
| 607 |
oldest = argmin([pop.members[member].birth for member=1:pop.n])
|
| 608 |
pop.members[oldest] = baby
|
|
|
|
| 614 |
# printing the fittest equation every 10% through
|
| 615 |
function run(
|
| 616 |
pop::Population,
|
| 617 |
+
ncycles::Integer;
|
|
|
|
| 618 |
verbosity::Integer=0
|
| 619 |
)::Population
|
| 620 |
|
| 621 |
allT = LinRange(1.0f0, 0.0f0, ncycles)
|
| 622 |
for iT in 1:size(allT)[1]
|
| 623 |
if annealing
|
| 624 |
+
pop = regEvolCycle(pop, allT[iT])
|
| 625 |
else
|
| 626 |
+
pop = regEvolCycle(pop, 1.0f0)
|
| 627 |
end
|
| 628 |
|
| 629 |
if verbosity > 0 && (iT % verbosity == 0)
|
|
|
|
| 711 |
|
| 712 |
function fullRun(niterations::Integer;
|
| 713 |
npop::Integer=300,
|
|
|
|
| 714 |
ncyclesperiteration::Integer=3000,
|
| 715 |
fractionReplaced::Float32=0.1f0,
|
| 716 |
verbosity::Integer=0,
|
|
|
|
| 727 |
for k=1:niterations
|
| 728 |
# Spawn threads to run indepdent evolutions, then gather them
|
| 729 |
@inbounds Threads.@threads for i=1:nthreads
|
| 730 |
+
allPops[i] = run(allPops[i], ncyclesperiteration, verbosity=verbosity)
|
| 731 |
bestSubPops[i] = bestSubPop(allPops[i], topn=topn)
|
| 732 |
for j=1:bestSubPops[i].n
|
| 733 |
bestSubPops[i].members[j].tree = simplifyTree(bestSubPops[i].members[j].tree)
|
eureqa.py
CHANGED
|
@@ -21,6 +21,7 @@ default_weightDoNothing = 1
|
|
| 21 |
default_result = 1
|
| 22 |
default_topn = 10
|
| 23 |
default_parsimony = 0.0
|
|
|
|
| 24 |
|
| 25 |
|
| 26 |
def eureqa(X=None, y=None, threads=4,
|
|
@@ -46,6 +47,7 @@ def eureqa(X=None, y=None, threads=4,
|
|
| 46 |
weightMutateOperator=default_weightMutateOperator,
|
| 47 |
weightRandomize=default_weightRandomize,
|
| 48 |
weightSimplify=default_weightSimplify,
|
|
|
|
| 49 |
timeout=None,
|
| 50 |
equation_file='hall_of_fame.csv',
|
| 51 |
test='simple1',
|
|
@@ -138,6 +140,8 @@ const fractionReplacedHof = {fractionReplacedHof}f0
|
|
| 138 |
const shouldOptimizeConstants = {'true' if shouldOptimizeConstants else 'false'}
|
| 139 |
const hofFile = "{equation_file}"
|
| 140 |
const nthreads = {threads:d}
|
|
|
|
|
|
|
| 141 |
const mutationWeights = [
|
| 142 |
{weightMutateConstant:f},
|
| 143 |
{weightMutateOperator:f},
|
|
@@ -175,7 +179,7 @@ const y = convert(Array{Float32, 1}, """f"{y_str})""""
|
|
| 175 |
'julia -O3',
|
| 176 |
f'--threads {threads}',
|
| 177 |
'-e',
|
| 178 |
-
f'\'include(".hyperparams_{rand_string}.jl"); include(".dataset_{rand_string}.jl"); include("eureqa.jl"); fullRun({niterations:d}, npop={npop:d},
|
| 179 |
]
|
| 180 |
if timeout is not None:
|
| 181 |
command = [f'timeout {timeout}'] + command
|
|
@@ -203,6 +207,7 @@ if __name__ == "__main__":
|
|
| 203 |
parser.add_argument("--npop", type=int, default=int(default_npop), help="Number of members per population")
|
| 204 |
parser.add_argument("--ncyclesperiteration", type=int, default=10000, help="Number of evolutionary cycles per migration")
|
| 205 |
parser.add_argument("--topn", type=int, default=int(default_topn), help="How many best species to distribute from each population")
|
|
|
|
| 206 |
parser.add_argument("--fractionReplacedHof", type=float, default=default_fractionReplacedHof, help="Fraction of population to replace with hall of fame")
|
| 207 |
parser.add_argument("--fractionReplaced", type=float, default=default_fractionReplaced, help="Fraction of population to replace with best from other populations")
|
| 208 |
parser.add_argument("--weightAddNode", type=float, default=default_weightAddNode)
|
|
|
|
| 21 |
default_result = 1
|
| 22 |
default_topn = 10
|
| 23 |
default_parsimony = 0.0
|
| 24 |
+
default_perturbationFactor = 1.0
|
| 25 |
|
| 26 |
|
| 27 |
def eureqa(X=None, y=None, threads=4,
|
|
|
|
| 47 |
weightMutateOperator=default_weightMutateOperator,
|
| 48 |
weightRandomize=default_weightRandomize,
|
| 49 |
weightSimplify=default_weightSimplify,
|
| 50 |
+
perturbationFactor=default_perturbationFactor,
|
| 51 |
timeout=None,
|
| 52 |
equation_file='hall_of_fame.csv',
|
| 53 |
test='simple1',
|
|
|
|
| 140 |
const shouldOptimizeConstants = {'true' if shouldOptimizeConstants else 'false'}
|
| 141 |
const hofFile = "{equation_file}"
|
| 142 |
const nthreads = {threads:d}
|
| 143 |
+
const perturbationFactor = {perturbationFactor:f}f0
|
| 144 |
+
const annealing = {"true" if annealing else "false"}
|
| 145 |
const mutationWeights = [
|
| 146 |
{weightMutateConstant:f},
|
| 147 |
{weightMutateOperator:f},
|
|
|
|
| 179 |
'julia -O3',
|
| 180 |
f'--threads {threads}',
|
| 181 |
'-e',
|
| 182 |
+
f'\'include(".hyperparams_{rand_string}.jl"); include(".dataset_{rand_string}.jl"); include("eureqa.jl"); fullRun({niterations:d}, npop={npop:d}, ncyclesperiteration={ncyclesperiteration:d}, fractionReplaced={fractionReplaced:f}f0, verbosity=round(Int32, {verbosity:f}), topn={topn:d})\'',
|
| 183 |
]
|
| 184 |
if timeout is not None:
|
| 185 |
command = [f'timeout {timeout}'] + command
|
|
|
|
| 207 |
parser.add_argument("--npop", type=int, default=int(default_npop), help="Number of members per population")
|
| 208 |
parser.add_argument("--ncyclesperiteration", type=int, default=10000, help="Number of evolutionary cycles per migration")
|
| 209 |
parser.add_argument("--topn", type=int, default=int(default_topn), help="How many best species to distribute from each population")
|
| 210 |
+
parser.add_argument("--perturbationFactor", type=float, default=default_perturbationFactor)
|
| 211 |
parser.add_argument("--fractionReplacedHof", type=float, default=default_fractionReplacedHof, help="Fraction of population to replace with hall of fame")
|
| 212 |
parser.add_argument("--fractionReplaced", type=float, default=default_fractionReplaced, help="Fraction of population to replace with best from other populations")
|
| 213 |
parser.add_argument("--weightAddNode", type=float, default=default_weightAddNode)
|
hyperparamopt.py
CHANGED
|
@@ -38,7 +38,7 @@ def run_trial(args):
|
|
| 38 |
args[key] = int(args[key])
|
| 39 |
|
| 40 |
|
| 41 |
-
total_steps =
|
| 42 |
niterations = args['niterations']
|
| 43 |
npop = args['npop']
|
| 44 |
if niterations == 0 or npop == 0:
|
|
@@ -57,7 +57,7 @@ def run_trial(args):
|
|
| 57 |
|
| 58 |
args['weightDoNothing'] = 1.0
|
| 59 |
|
| 60 |
-
maxTime =
|
| 61 |
ntrials = 2
|
| 62 |
equation_file = f'.hall_of_fame_{np.random.rand():f}.csv'
|
| 63 |
|
|
@@ -73,13 +73,13 @@ def run_trial(args):
|
|
| 73 |
print(f"Starting", str(args))
|
| 74 |
try:
|
| 75 |
trials = []
|
| 76 |
-
for i in range(
|
| 77 |
print(f"Starting test {i}")
|
| 78 |
for j in range(ntrials):
|
| 79 |
print(f"Starting trial {j}")
|
| 80 |
trial = eureqa.eureqa(
|
| 81 |
test=f"simple{i}",
|
| 82 |
-
threads=
|
| 83 |
binary_operators=["plus", "mult", "pow", "div"],
|
| 84 |
unary_operators=["cos", "exp", "sin", "loga", "abs"],
|
| 85 |
equation_file=equation_file,
|
|
@@ -114,6 +114,7 @@ space = {
|
|
| 114 |
'alpha': hp.lognormal('alpha', np.log(10.0), 1.0),
|
| 115 |
'fractionReplacedHof': hp.lognormal('fractionReplacedHof', np.log(0.1), 1.0),
|
| 116 |
'fractionReplaced': hp.lognormal('fractionReplaced', np.log(0.1), 1.0),
|
|
|
|
| 117 |
'weightMutateConstant': hp.lognormal('weightMutateConstant', np.log(4.0), 1.0),
|
| 118 |
'weightMutateOperator': hp.lognormal('weightMutateOperator', np.log(0.5), 1.0),
|
| 119 |
'weightAddNode': hp.lognormal('weightAddNode', np.log(0.5), 1.0),
|
|
|
|
| 38 |
args[key] = int(args[key])
|
| 39 |
|
| 40 |
|
| 41 |
+
total_steps = 10*100*1000
|
| 42 |
niterations = args['niterations']
|
| 43 |
npop = args['npop']
|
| 44 |
if niterations == 0 or npop == 0:
|
|
|
|
| 57 |
|
| 58 |
args['weightDoNothing'] = 1.0
|
| 59 |
|
| 60 |
+
maxTime = 30
|
| 61 |
ntrials = 2
|
| 62 |
equation_file = f'.hall_of_fame_{np.random.rand():f}.csv'
|
| 63 |
|
|
|
|
| 73 |
print(f"Starting", str(args))
|
| 74 |
try:
|
| 75 |
trials = []
|
| 76 |
+
for i in range(3, 6):
|
| 77 |
print(f"Starting test {i}")
|
| 78 |
for j in range(ntrials):
|
| 79 |
print(f"Starting trial {j}")
|
| 80 |
trial = eureqa.eureqa(
|
| 81 |
test=f"simple{i}",
|
| 82 |
+
threads=4,
|
| 83 |
binary_operators=["plus", "mult", "pow", "div"],
|
| 84 |
unary_operators=["cos", "exp", "sin", "loga", "abs"],
|
| 85 |
equation_file=equation_file,
|
|
|
|
| 114 |
'alpha': hp.lognormal('alpha', np.log(10.0), 1.0),
|
| 115 |
'fractionReplacedHof': hp.lognormal('fractionReplacedHof', np.log(0.1), 1.0),
|
| 116 |
'fractionReplaced': hp.lognormal('fractionReplaced', np.log(0.1), 1.0),
|
| 117 |
+
'perturbationFactor': hp.lognormal('perturbationFactor', np.log(1.0), 1.0),
|
| 118 |
'weightMutateConstant': hp.lognormal('weightMutateConstant', np.log(4.0), 1.0),
|
| 119 |
'weightMutateOperator': hp.lognormal('weightMutateOperator', np.log(0.5), 1.0),
|
| 120 |
'weightAddNode': hp.lognormal('weightAddNode', np.log(0.5), 1.0),
|