Spaces:
Sleeping
Sleeping
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;
|