Spaces:
Running
Running
MilesCranmer
commited on
Commit
•
a3a2513
1
Parent(s):
9b9db9e
Allow numpy arrays to be passed
Browse files
README.md
CHANGED
@@ -21,7 +21,8 @@ usage: eureqa.py [-h] [--threads THREADS] [--parsimony PARSIMONY]
|
|
21 |
[--fractionReplaced FRACTIONREPLACED] [--migration MIGRATION]
|
22 |
[--hofMigration HOFMIGRATION]
|
23 |
[--shouldOptimizeConstants SHOULDOPTIMIZECONSTANTS]
|
24 |
-
[--annealing ANNEALING]
|
|
|
25 |
[--binary-operators BINARY_OPERATORS [BINARY_OPERATORS ...]]
|
26 |
[--unary-operators UNARY_OPERATORS]
|
27 |
|
@@ -56,6 +57,10 @@ optional arguments:
|
|
56 |
that much) (default: True)
|
57 |
--annealing ANNEALING
|
58 |
Whether to use simulated annealing (default: True)
|
|
|
|
|
|
|
|
|
59 |
--binary-operators BINARY_OPERATORS [BINARY_OPERATORS ...]
|
60 |
Binary operators. Make sure they are defined in
|
61 |
operators.jl (default: ['plus', 'mul'])
|
|
|
21 |
[--fractionReplaced FRACTIONREPLACED] [--migration MIGRATION]
|
22 |
[--hofMigration HOFMIGRATION]
|
23 |
[--shouldOptimizeConstants SHOULDOPTIMIZECONSTANTS]
|
24 |
+
[--annealing ANNEALING] [--equation_file EQUATION_FILE]
|
25 |
+
[--test TEST]
|
26 |
[--binary-operators BINARY_OPERATORS [BINARY_OPERATORS ...]]
|
27 |
[--unary-operators UNARY_OPERATORS]
|
28 |
|
|
|
57 |
that much) (default: True)
|
58 |
--annealing ANNEALING
|
59 |
Whether to use simulated annealing (default: True)
|
60 |
+
--equation_file EQUATION_FILE
|
61 |
+
File to dump best equations to (default:
|
62 |
+
hall_of_fame.csv)
|
63 |
+
--test TEST Which test to run (default: simple1)
|
64 |
--binary-operators BINARY_OPERATORS [BINARY_OPERATORS ...]
|
65 |
Binary operators. Make sure they are defined in
|
66 |
operators.jl (default: ['plus', 'mul'])
|
eureqa.jl
CHANGED
@@ -557,7 +557,6 @@ function fullRun(niterations::Integer;
|
|
557 |
verbosity::Integer=0,
|
558 |
topn::Integer=10
|
559 |
)
|
560 |
-
debug(verbosity, "Lets try to learn (x2^2 + cos(x3)) using regularized evolution from scratch")
|
561 |
debug(verbosity, "Running with $nthreads threads")
|
562 |
# Generate random initial populations
|
563 |
allPops = [Population(npop, 3) for j=1:nthreads]
|
|
|
557 |
verbosity::Integer=0,
|
558 |
topn::Integer=10
|
559 |
)
|
|
|
560 |
debug(verbosity, "Running with $nthreads threads")
|
561 |
# Generate random initial populations
|
562 |
allPops = [Population(npop, 3) for j=1:nthreads]
|
eureqa.py
CHANGED
@@ -2,9 +2,11 @@ import os
|
|
2 |
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
|
3 |
from collections import namedtuple
|
4 |
import pathlib
|
|
|
|
|
5 |
|
6 |
|
7 |
-
def eureqa(threads=4, parsimony=1e-3, alpha=10,
|
8 |
maxsize=20, migration=True,
|
9 |
hofMigration=True, fractionReplacedHof=0.1,
|
10 |
shouldOptimizeConstants=True,
|
@@ -12,8 +14,64 @@ def eureqa(threads=4, parsimony=1e-3, alpha=10,
|
|
12 |
unary_operators=["cos", "exp", "sin"],
|
13 |
niterations=20, npop=100, annealing=True,
|
14 |
ncyclesperiteration=5000, fractionReplaced=0.1,
|
15 |
-
topn=10, equation_file='hall_of_fame.csv'
|
|
|
16 |
):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
|
18 |
def_hyperparams = f"""
|
19 |
include("operators.jl")
|
@@ -48,12 +106,18 @@ def eureqa(threads=4, parsimony=1e-3, alpha=10,
|
|
48 |
##################
|
49 |
"""
|
50 |
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
def_datasets = """
|
52 |
# Here is the function we want to learn (x2^2 + cos(x3) + 5)
|
53 |
##########################
|
54 |
# # Dataset to learn
|
55 |
-
const X = convert(Array{Float32, 2},
|
56 |
-
const y = convert(Array{Float32, 1},
|
57 |
##########################
|
58 |
"""
|
59 |
|
@@ -63,18 +127,24 @@ def eureqa(threads=4, parsimony=1e-3, alpha=10,
|
|
63 |
with open('.dataset.jl', 'w') as f:
|
64 |
print(def_datasets, file=f)
|
65 |
|
66 |
-
command =
|
67 |
f'cd {pathlib.Path(__file__).parent.absolute()}', #Move to filepath of code
|
68 |
'&&',
|
69 |
'julia -O3',
|
70 |
f'--threads {threads}',
|
71 |
'-e',
|
72 |
-
f'\'include("eureqa.jl"); fullRun({niterations:d}, npop={npop:d}, annealing={"true" if annealing else "false"}, ncyclesperiteration={ncyclesperiteration:d}, fractionReplaced={fractionReplaced:f}f0, verbosity=round(Int32, 1e9), topn={topn:d})\''
|
73 |
'&&',
|
74 |
f'cd {pathlib.Path().absolute()}',
|
75 |
-
]
|
76 |
import os
|
77 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
|
79 |
|
80 |
|
@@ -97,6 +167,7 @@ if __name__ == "__main__":
|
|
97 |
parser.add_argument("--shouldOptimizeConstants", type=bool, default=True, help="Whether to use classical optimization on constants before every migration (doesn't impact performance that much)")
|
98 |
parser.add_argument("--annealing", type=bool, default=True, help="Whether to use simulated annealing")
|
99 |
parser.add_argument("--equation_file", type=str, default='hall_of_fame.csv', help="File to dump best equations to")
|
|
|
100 |
|
101 |
parser.add_argument(
|
102 |
"--binary-operators", type=str, nargs="+", default=["plus", "mul"],
|
|
|
2 |
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
|
3 |
from collections import namedtuple
|
4 |
import pathlib
|
5 |
+
import numpy as np
|
6 |
+
import pandas as pd
|
7 |
|
8 |
|
9 |
+
def eureqa(X=None, y=None, threads=4, parsimony=1e-3, alpha=10,
|
10 |
maxsize=20, migration=True,
|
11 |
hofMigration=True, fractionReplacedHof=0.1,
|
12 |
shouldOptimizeConstants=True,
|
|
|
14 |
unary_operators=["cos", "exp", "sin"],
|
15 |
niterations=20, npop=100, annealing=True,
|
16 |
ncyclesperiteration=5000, fractionReplaced=0.1,
|
17 |
+
topn=10, equation_file='hall_of_fame.csv',
|
18 |
+
test='simple1'
|
19 |
):
|
20 |
+
"""Either provide a 2D numpy array for X, 1D array for y, or declare a test to run.
|
21 |
+
|
22 |
+
--threads THREADS Number of threads (default: 4)
|
23 |
+
--parsimony PARSIMONY
|
24 |
+
How much to punish complexity (default: 0.001)
|
25 |
+
--alpha ALPHA Scaling of temperature (default: 10)
|
26 |
+
--maxsize MAXSIZE Max size of equation (default: 20)
|
27 |
+
--niterations NITERATIONS
|
28 |
+
Number of total migration periods (default: 20)
|
29 |
+
--npop NPOP Number of members per population (default: 100)
|
30 |
+
--ncyclesperiteration NCYCLESPERITERATION
|
31 |
+
Number of evolutionary cycles per migration (default:
|
32 |
+
5000)
|
33 |
+
--topn TOPN How many best species to distribute from each
|
34 |
+
population (default: 10)
|
35 |
+
--fractionReplacedHof FRACTIONREPLACEDHOF
|
36 |
+
Fraction of population to replace with hall of fame
|
37 |
+
(default: 0.1)
|
38 |
+
--fractionReplaced FRACTIONREPLACED
|
39 |
+
Fraction of population to replace with best from other
|
40 |
+
populations (default: 0.1)
|
41 |
+
--migration MIGRATION
|
42 |
+
Whether to migrate (default: True)
|
43 |
+
--hofMigration HOFMIGRATION
|
44 |
+
Whether to have hall of fame migration (default: True)
|
45 |
+
--shouldOptimizeConstants SHOULDOPTIMIZECONSTANTS
|
46 |
+
Whether to use classical optimization on constants
|
47 |
+
before every migration (doesn't impact performance
|
48 |
+
that much) (default: True)
|
49 |
+
--annealing ANNEALING
|
50 |
+
Whether to use simulated annealing (default: True)
|
51 |
+
--equation_file EQUATION_FILE
|
52 |
+
File to dump best equations to (default:
|
53 |
+
hall_of_fame.csv)
|
54 |
+
--test TEST Which test to run (default: simple1)
|
55 |
+
--binary-operators BINARY_OPERATORS [BINARY_OPERATORS ...]
|
56 |
+
Binary operators. Make sure they are defined in
|
57 |
+
operators.jl (default: ['plus', 'mul'])
|
58 |
+
--unary-operators UNARY_OPERATORS
|
59 |
+
Unary operators. Make sure they are defined in
|
60 |
+
operators.jl (default: ['exp', 'sin', 'cos'])
|
61 |
+
"""
|
62 |
+
|
63 |
+
if isinstance(binary_operators, str): binary_operators = [binary_operators]
|
64 |
+
if isinstance(unary_operators, str): unary_operators = [unary_operators]
|
65 |
+
|
66 |
+
if X is None:
|
67 |
+
if test == 'simple1':
|
68 |
+
eval_str = "X[:, 2]**2 + np.cos(X[:, 3]) - 5"
|
69 |
+
elif test == 'simple2':
|
70 |
+
eval_str = "X[:, 2]**3.5 + 1/abs(X[:, 0])"
|
71 |
+
|
72 |
+
X = np.random.randn(100, 5)*3
|
73 |
+
y = eval(eval_str)
|
74 |
+
print("Runing on", eval_str)
|
75 |
|
76 |
def_hyperparams = f"""
|
77 |
include("operators.jl")
|
|
|
106 |
##################
|
107 |
"""
|
108 |
|
109 |
+
assert len(X.shape) == 2
|
110 |
+
assert len(y.shape) == 1
|
111 |
+
|
112 |
+
X_str = str(X.tolist()).replace('],', '];').replace(',', '')
|
113 |
+
y_str = str(y.tolist())
|
114 |
+
|
115 |
def_datasets = """
|
116 |
# Here is the function we want to learn (x2^2 + cos(x3) + 5)
|
117 |
##########################
|
118 |
# # Dataset to learn
|
119 |
+
const X = convert(Array{Float32, 2}, """f"{X_str})""""
|
120 |
+
const y = convert(Array{Float32, 1}, """f"{y_str})""""
|
121 |
##########################
|
122 |
"""
|
123 |
|
|
|
127 |
with open('.dataset.jl', 'w') as f:
|
128 |
print(def_datasets, file=f)
|
129 |
|
130 |
+
command = [
|
131 |
f'cd {pathlib.Path(__file__).parent.absolute()}', #Move to filepath of code
|
132 |
'&&',
|
133 |
'julia -O3',
|
134 |
f'--threads {threads}',
|
135 |
'-e',
|
136 |
+
f'\'include("eureqa.jl"); fullRun({niterations:d}, npop={npop:d}, annealing={"true" if annealing else "false"}, ncyclesperiteration={ncyclesperiteration:d}, fractionReplaced={fractionReplaced:f}f0, verbosity=round(Int32, 1e9), topn={topn:d})\'',
|
137 |
'&&',
|
138 |
f'cd {pathlib.Path().absolute()}',
|
139 |
+
]
|
140 |
import os
|
141 |
+
cur_cmd = ' '.join(command[:-2])
|
142 |
+
print("Running on", cur_cmd)
|
143 |
+
os.system(cur_cmd)
|
144 |
+
output = pd.read_csv(equation_file, sep="|")
|
145 |
+
os.system(command[-1])
|
146 |
+
return output
|
147 |
+
|
148 |
|
149 |
|
150 |
|
|
|
167 |
parser.add_argument("--shouldOptimizeConstants", type=bool, default=True, help="Whether to use classical optimization on constants before every migration (doesn't impact performance that much)")
|
168 |
parser.add_argument("--annealing", type=bool, default=True, help="Whether to use simulated annealing")
|
169 |
parser.add_argument("--equation_file", type=str, default='hall_of_fame.csv', help="File to dump best equations to")
|
170 |
+
parser.add_argument("--test", type=str, default='simple1', help="Which test to run")
|
171 |
|
172 |
parser.add_argument(
|
173 |
"--binary-operators", type=str, nargs="+", default=["plus", "mul"],
|
operators.jl
CHANGED
@@ -2,3 +2,4 @@
|
|
2 |
plus(x::Float32, y::Float32)::Float32 = x+y
|
3 |
mult(x::Float32, y::Float32)::Float32 = x*y;
|
4 |
pow(x::Float32, y::Float32)::Float32 = sign(x)*abs(x)^y;
|
|
|
|
2 |
plus(x::Float32, y::Float32)::Float32 = x+y
|
3 |
mult(x::Float32, y::Float32)::Float32 = x*y;
|
4 |
pow(x::Float32, y::Float32)::Float32 = sign(x)*abs(x)^y;
|
5 |
+
div(x::Float32, y::Float32)::Float32 = x/y;
|