MilesCranmer commited on
Commit
cfca8a4
1 Parent(s): fa28749

Add a python interface

Browse files
Files changed (7) hide show
  1. .gitignore +2 -0
  2. README.md +11 -16
  3. dataset.jl +0 -7
  4. eureqa.jl +2 -2
  5. eureqa.py +84 -0
  6. hyperparams.jl +0 -33
  7. operators.jl +3 -0
.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ .dataset.jl
2
+ .hyperparams.jl
README.md CHANGED
@@ -1,25 +1,20 @@
1
- # Running:
2
 
3
- You can execute the program from the command line with
 
 
 
 
 
4
  ```bash
5
- julia --threads 6 -O3 -e 'include("paralleleureqa.jl"); fullRun(20, npop=100, annealing=true, ncyclesperiteration=5000, fractionReplaced=0.1f0, verbosity=round(Int32, 1e9), topn=10)'
6
  ```
7
 
8
- Modify the hyperparameters in `hyperparams.jl` and the dataset in `dataset.jl`
9
- (see below for options).
10
-
11
- The first argument to `fullRun` is the number of migration periods to run,
12
- with `ncyclesperiteration` determining how many generations
13
- per migration period. `npop` is the number of population members.
14
- `annealing` determines whether to stay in exploration mode,
15
- or tune it down with each cycle. `fractionReplaced` is
16
- how much of the population is replaced by migrated equations each
17
- step. `topn` is the number of top members of each population
18
- to migrate.
19
 
20
 
21
- Run it with threading turned on using:
22
- `julia --threads auto -O3 myfile.jl`
23
 
24
  ## Modification
25
 
 
1
+ # Eureqa.jl
2
 
3
+ Symbolic regression built on Eureqa, and interfaced by Python.
4
+ Uses regularized evolution and simulated annealing.
5
+
6
+ ## Running:
7
+
8
+ You can execute the program from the command line with, for example:
9
  ```bash
10
+ python eureqa.py --threads 8 --binary-operators plus mult
11
  ```
12
 
13
+ You can see all hyperparameters in the function `eureqa` inside `eureqa.py`.
14
+ This function generates Julia code which is then executed
15
+ by `eureqa.jl` and `paralleleureqa.jl`.
 
 
 
 
 
 
 
 
16
 
17
 
 
 
18
 
19
  ## Modification
20
 
dataset.jl DELETED
@@ -1,7 +0,0 @@
1
- # Here is the function we want to learn (x2^2 + cos(x3) + 5)
2
-
3
- ##########################
4
- # # Dataset to learn
5
- const X = convert(Array{Float32, 2}, randn(100, 5)*2)
6
- const y = convert(Array{Float32, 1}, ((cx,)->cx^2).(X[:, 2]) + cos.(X[:, 3]) .- 5)
7
- ##########################
 
 
 
 
 
 
 
 
eureqa.jl CHANGED
@@ -1,5 +1,5 @@
1
- include("hyperparams.jl")
2
- include("dataset.jl")
3
  import Optim
4
 
5
  const maxdegree = 2
 
1
+ include(".hyperparams.jl")
2
+ include(".dataset.jl")
3
  import Optim
4
 
5
  const maxdegree = 2
eureqa.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from argparse import ArgumentParser
3
+ from collections import namedtuple
4
+
5
+
6
+ def eureqa(threads=4, parsimony=1e-3, alpha=10,
7
+ maxsize=20, migration=True,
8
+ hofMigration=True, fractionReplacedHof=0.1,
9
+ shouldOptimizeConstants=True,
10
+ binary_operators=["plus", "mult"],
11
+ unary_operators=["cos", "exp", "sin"],
12
+ niterations=20, npop=100, annealing=True,
13
+ ncyclesperiteration=5000, fractionReplaced=0.1,
14
+ topn=10
15
+ ):
16
+
17
+ def_hyperparams = f"""
18
+ include("operators.jl")
19
+ ##########################
20
+ # # Allowed operators
21
+ # (Apparently using const for globals helps speed)
22
+ const binops = {'[' + ', '.join(binary_operators) + ']'}
23
+ const unaops = {'[' + ', '.join(unary_operators) + ']'}
24
+ ##########################
25
+
26
+ # How many equations to search when replacing
27
+ const ns=10;
28
+
29
+ ##################
30
+ # Hyperparameters
31
+ # How much to punish complexity
32
+ const parsimony = {parsimony:f}f0
33
+ # How much to scale temperature by (T between 0 and 1)
34
+ const alpha = {alpha:f}f0
35
+ # Max size of an equation (too large will slow program down)
36
+ const maxsize = {maxsize:d}
37
+ # Whether to migrate between threads (you should)
38
+ const migration = {'true' if migration else 'false'}
39
+ # Whether to re-introduce best examples seen (helps a lot)
40
+ const hofMigration = {'true' if hofMigration else 'false'}
41
+ # Fraction of population to replace with hall of fame
42
+ const fractionReplacedHof = {fractionReplacedHof}f0
43
+ # Optimize constants
44
+ const shouldOptimizeConstants = {'true' if shouldOptimizeConstants else 'false'}
45
+ ##################
46
+ """
47
+
48
+ def_datasets = """
49
+ # Here is the function we want to learn (x2^2 + cos(x3) + 5)
50
+ ##########################
51
+ # # Dataset to learn
52
+ const X = convert(Array{Float32, 2}, randn(100, 5)*2)
53
+ const y = convert(Array{Float32, 1}, ((cx,)->cx^2).(X[:, 2]) + cos.(X[:, 3]) .- 5)
54
+ ##########################
55
+ """
56
+
57
+ with open('.hyperparams.jl', 'w') as f:
58
+ print(def_hyperparams, file=f)
59
+ with open('.dataset.jl', 'w') as f:
60
+ print(def_datasets, file=f)
61
+
62
+ command = ' '.join([
63
+ 'julia -O3',
64
+ f'--threads {threads}',
65
+ '-e',
66
+ f'\'include("paralleleureqa.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})\''
67
+ ])
68
+ import os
69
+ os.system(command)
70
+
71
+
72
+ if __name__ == "__main__":
73
+ parser = ArgumentParser()
74
+ parser.add_argument("--threads", type=int, default=4, help="number of threads")
75
+ parser.add_argument("--parsimony", type=float, default=4, help="number of threads")
76
+ parser.add_argument(
77
+ "--binary-operators", type=str, nargs="+", default=["plus", "mul"],
78
+ help="Binary operators. Make sure they are defined in operators.jl")
79
+ parser.add_argument(
80
+ "--unary-operators", type=str, default=["exp", "sin", "cos"],
81
+ help="Unary operators. Make sure they are defined in operators.jl")
82
+ args = vars(parser.parse_args()) #dict
83
+
84
+ run(**args)
hyperparams.jl DELETED
@@ -1,33 +0,0 @@
1
- # Define allowed operators
2
- plus(x::Float32, y::Float32)::Float32 = x+y
3
- mult(x::Float32, y::Float32)::Float32 = x*y;
4
-
5
- ##########################
6
- # # Allowed operators
7
- # (Apparently using const for globals helps speed)
8
- const binops = [plus, mult]
9
- const unaops = [sin, cos, exp]
10
- ##########################
11
-
12
- # How many equations to search when replacing
13
- const ns=10;
14
-
15
- ##################
16
- # Hyperparameters
17
- # How much to punish complexity
18
- const parsimony = 1f-3
19
- # How much to scale temperature by (T between 0 and 1)
20
- const alpha = 10.0f0
21
- # Max size of an equation (too large will slow program down)
22
- const maxsize = 20
23
- # Whether to migrate between threads (you should)
24
- const migration = true
25
- # Whether to re-introduce best examples seen (helps a lot)
26
- const hofMigration = true
27
- # Fraction of population to replace with hall of fame
28
- const fractionReplacedHof = 0.1f0
29
- # Optimize constants
30
- const shouldOptimizeConstants = true
31
- ##################
32
-
33
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
operators.jl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # Define allowed operators
2
+ plus(x::Float32, y::Float32)::Float32 = x+y
3
+ mult(x::Float32, y::Float32)::Float32 = x*y;