Spaces:
Running
Running
MilesCranmer
commited on
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),
|