MilesCranmer commited on
Commit
a95ae71
1 Parent(s): 9b8f588

Fix issues with hyperopt code

Browse files
Files changed (3) hide show
  1. eureqa.py +4 -3
  2. hyperparamopt.py +63 -32
  3. operators.jl +4 -3
eureqa.py CHANGED
@@ -49,6 +49,7 @@ def eureqa(X=None, y=None, threads=4,
49
  timeout=None,
50
  equation_file='hall_of_fame.csv',
51
  test='simple1',
 
52
  maxsize=20,
53
  ):
54
  """Run symbolic regression to fit f(X[i, :]) ~ y[i] for all i.
@@ -111,13 +112,13 @@ def eureqa(X=None, y=None, threads=4,
111
  if test == 'simple1':
112
  eval_str = "np.sign(X[:, 2])*np.abs(X[:, 2])**2.5 + 5*np.cos(X[:, 3]) - 5"
113
  elif test == 'simple2':
114
- eval_str = "np.sign(X[:, 2])*np.abs(X[:, 2])**3.5 + 1/np.abs(X[:, 0])"
115
  elif test == 'simple3':
116
  eval_str = "np.exp(X[:, 0]/2) + 12.0 + np.log(np.abs(X[:, 0])*10 + 1)"
117
  elif test == 'simple4':
118
  eval_str = "1.0 + 3*X[:, 0]**2 - 0.5*X[:, 0]**3 + 0.1*X[:, 0]**4"
119
  elif test == 'simple5':
120
- eval_str = "(np.exp(X[:, 3]) + 3)/(X[:, 1] + np.cos(X[:, 0]))"
121
 
122
  X = np.random.randn(100, 5)*3
123
  y = eval(eval_str)
@@ -172,7 +173,7 @@ const y = convert(Array{Float32, 1}, """f"{y_str})""""
172
  'julia -O3',
173
  f'--threads {threads}',
174
  '-e',
175
- f'\'include(".hyperparams_{rand_string}.jl"); include(".dataset_{rand_string}.jl"); 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})\'',
176
  ]
177
  if timeout is not None:
178
  command = [f'timeout {timeout}'] + command
 
49
  timeout=None,
50
  equation_file='hall_of_fame.csv',
51
  test='simple1',
52
+ verbosity=1e9,
53
  maxsize=20,
54
  ):
55
  """Run symbolic regression to fit f(X[i, :]) ~ y[i] for all i.
 
112
  if test == 'simple1':
113
  eval_str = "np.sign(X[:, 2])*np.abs(X[:, 2])**2.5 + 5*np.cos(X[:, 3]) - 5"
114
  elif test == 'simple2':
115
+ eval_str = "np.sign(X[:, 2])*np.abs(X[:, 2])**3.5 + 1/(np.abs(X[:, 0])+1)"
116
  elif test == 'simple3':
117
  eval_str = "np.exp(X[:, 0]/2) + 12.0 + np.log(np.abs(X[:, 0])*10 + 1)"
118
  elif test == 'simple4':
119
  eval_str = "1.0 + 3*X[:, 0]**2 - 0.5*X[:, 0]**3 + 0.1*X[:, 0]**4"
120
  elif test == 'simple5':
121
+ eval_str = "(np.exp(X[:, 3]) + 3)/(np.abs(X[:, 1]) + np.cos(X[:, 0]) + 1.1)"
122
 
123
  X = np.random.randn(100, 5)*3
124
  y = eval(eval_str)
 
173
  'julia -O3',
174
  f'--threads {threads}',
175
  '-e',
176
+ f'\'include(".hyperparams_{rand_string}.jl"); include(".dataset_{rand_string}.jl"); 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, {verbosity:f}), topn={topn:d})\'',
177
  ]
178
  if timeout is not None:
179
  command = [f'timeout {timeout}'] + command
hyperparamopt.py CHANGED
@@ -5,6 +5,19 @@ import pickle as pkl
5
  import hyperopt
6
  from hyperopt import hp, fmin, tpe, Trials
7
  import eureqa
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
 
10
  #Change the following code to your file
@@ -21,45 +34,68 @@ def run_trial(args):
21
  """
22
 
23
  print("Running on", args)
24
- for key in 'niterations npop ncyclesperiteration topn'.split(' '):
25
  args[key] = int(args[key])
26
 
27
- if args['npop'] < 50 or args['ncyclesperiteration'] < 3:
 
 
 
 
 
 
 
 
28
  print("Bad parameters")
29
  return {'status': 'ok', 'loss': np.inf}
30
 
31
- def handler(signum, frame):
32
- print("Took too long. Skipping.")
33
- raise ValueError("Takes too long")
34
 
35
- maxTime = 120
36
- ntrials = 3
 
 
37
  equation_file = f'.hall_of_fame_{np.random.rand():f}.csv'
38
 
 
 
 
 
 
 
 
 
 
 
39
  try:
40
  trials = []
41
- for i in range(1, 4):
42
- subtrials = []
43
  for j in range(ntrials):
 
44
  trial = eureqa.eureqa(
45
  test=f"simple{i}",
46
- threads=4,
47
  binary_operators=["plus", "mult", "pow", "div"],
48
- unary_operators=["cos", "exp", "sin", "log"],
49
  equation_file=equation_file,
50
  timeout=maxTime,
 
 
51
  **args)
52
  if len(trial) == 0: raise ValueError
53
- subtrials.append(np.min(trial['MSE']))
54
- trials.append(np.log(np.median(subtrials) + 0.1))
 
 
 
55
  except ValueError:
 
56
  return {
57
  'status': 'ok', # or 'fail' if nan loss
58
  'loss': np.inf
59
  }
60
-
61
  loss = np.average(trials)
62
- print(args, "got", loss)
63
 
64
  return {
65
  'status': 'ok', # or 'fail' if nan loss
@@ -68,22 +104,17 @@ def run_trial(args):
68
 
69
 
70
  space = {
71
- 'niterations': hp.qlognormal('niterations', np.log(10), 0.5, 1),
72
- 'npop': hp.qlognormal('npop', np.log(100), 0.5, 1),
73
- 'ncyclesperiteration': hp.qlognormal('ncyclesperiteration', np.log(5000), 0.5, 1),
74
- 'topn': hp.quniform('topn', 1, 30, 1),
75
- 'annealing': hp.choice('annealing', [False, True]),
76
- 'alpha': hp.lognormal('alpha', np.log(10.0), 0.5),
77
- 'parsimony': hp.lognormal('parsimony', np.log(1e-3), 0.5),
78
- 'fractionReplacedHof': hp.lognormal('fractionReplacedHof', np.log(0.1), 0.5),
79
- 'fractionReplaced': hp.lognormal('fractionReplaced', np.log(0.1), 0.5),
80
- 'weightMutateConstant': hp.lognormal('weightMutateConstant', np.log(4.0), 0.5),
81
- 'weightMutateOperator': hp.lognormal('weightMutateOperator', np.log(0.5), 0.5),
82
- 'weightAddNode': hp.lognormal('weightAddNode', np.log(0.5), 0.5),
83
- 'weightDeleteNode': hp.lognormal('weightDeleteNode', np.log(0.5), 0.5),
84
- 'weightSimplify': hp.lognormal('weightSimplify', np.log(0.05), 0.5),
85
- 'weightRandomize': hp.lognormal('weightRandomize', np.log(0.25), 0.5),
86
- 'weightDoNothing': hp.lognormal('weightDoNothing', np.log(1.0), 0.5),
87
  }
88
 
89
  ################################################################################
@@ -165,7 +196,7 @@ while True:
165
 
166
  # Merge with empty trials dataset:
167
  save_trials = merge_trials(hyperopt_trial, trials.trials[-n:])
168
- new_fname = TRIALS_FOLDER + '/' + str(np.random.randint(0, sys.maxsize)) + '.pkl'
169
  pkl.dump({'trials': save_trials, 'n': n}, open(new_fname, 'wb'))
170
  loaded_fnames.append(new_fname)
171
 
 
5
  import hyperopt
6
  from hyperopt import hp, fmin, tpe, Trials
7
  import eureqa
8
+ import time
9
+
10
+ import contextlib
11
+ import numpy as np
12
+
13
+ @contextlib.contextmanager
14
+ def temp_seed(seed):
15
+ state = np.random.get_state()
16
+ np.random.seed(seed)
17
+ try:
18
+ yield
19
+ finally:
20
+ np.random.set_state(state)
21
 
22
 
23
  #Change the following code to your file
 
34
  """
35
 
36
  print("Running on", args)
37
+ for key in 'niterations npop'.split(' '):
38
  args[key] = int(args[key])
39
 
40
+ total_steps = 10*100*5000
41
+ niterations = args['niterations']
42
+ npop = args['npop']
43
+ args['ncyclesperiteration'] = int(total_steps / (niterations * npop))
44
+ args['topn'] = 10
45
+ args['parsimony'] = 1e-3
46
+ args['annealing'] = True
47
+
48
+ if args['npop'] < 20 or args['ncyclesperiteration'] < 3:
49
  print("Bad parameters")
50
  return {'status': 'ok', 'loss': np.inf}
51
 
 
 
 
52
 
53
+ args['weightDoNothing'] = 1.0
54
+
55
+ maxTime = 2*60
56
+ ntrials = 2
57
  equation_file = f'.hall_of_fame_{np.random.rand():f}.csv'
58
 
59
+ with temp_seed(0):
60
+ X = np.random.randn(100, 5)*3
61
+
62
+ eval_str = ["np.sign(X[:, 2])*np.abs(X[:, 2])**2.5 + 5*np.cos(X[:, 3]) - 5",
63
+ "np.sign(X[:, 2])*np.abs(X[:, 2])**3.5 + 1/(np.abs(X[:, 0])+1)",
64
+ "np.exp(X[:, 0]/2) + 12.0 + np.log(np.abs(X[:, 0])*10 + 1)",
65
+ "1.0 + 3*X[:, 0]**2 - 0.5*X[:, 0]**3 + 0.1*X[:, 0]**4",
66
+ "(np.exp(X[:, 3]) + 3)/(np.abs(X[:, 1]) + np.cos(X[:, 0]) + 1.1)"]
67
+
68
+ print(f"Starting", str(args))
69
  try:
70
  trials = []
71
+ for i in range(1, 6):
72
+ print(f"Starting test {i}")
73
  for j in range(ntrials):
74
+ print(f"Starting trial {j}")
75
  trial = eureqa.eureqa(
76
  test=f"simple{i}",
77
+ threads=8,
78
  binary_operators=["plus", "mult", "pow", "div"],
79
+ unary_operators=["cos", "exp", "sin", "loga", "abs"],
80
  equation_file=equation_file,
81
  timeout=maxTime,
82
+ maxsize=25,
83
+ verbosity=0,
84
  **args)
85
  if len(trial) == 0: raise ValueError
86
+ trials.append(
87
+ np.min(trial['MSE'])**0.5 / np.std(eval(eval_str[i-1]))
88
+ )
89
+ print(f"Test {i} trial {j} with", str(args), f"got {trials[-1]}")
90
+
91
  except ValueError:
92
+ print(f"Broken", str(args))
93
  return {
94
  'status': 'ok', # or 'fail' if nan loss
95
  'loss': np.inf
96
  }
 
97
  loss = np.average(trials)
98
+ print(f"Finished with {loss}", str(args))
99
 
100
  return {
101
  'status': 'ok', # or 'fail' if nan loss
 
104
 
105
 
106
  space = {
107
+ 'niterations': hp.qlognormal('niterations', np.log(10), 1.0, 1),
108
+ 'npop': hp.qlognormal('npop', np.log(100), 1.0, 1),
109
+ 'alpha': hp.lognormal('alpha', np.log(10.0), 1.0),
110
+ 'fractionReplacedHof': hp.lognormal('fractionReplacedHof', np.log(0.1), 1.0),
111
+ 'fractionReplaced': hp.lognormal('fractionReplaced', np.log(0.1), 1.0),
112
+ 'weightMutateConstant': hp.lognormal('weightMutateConstant', np.log(4.0), 1.0),
113
+ 'weightMutateOperator': hp.lognormal('weightMutateOperator', np.log(0.5), 1.0),
114
+ 'weightAddNode': hp.lognormal('weightAddNode', np.log(0.5), 1.0),
115
+ 'weightDeleteNode': hp.lognormal('weightDeleteNode', np.log(0.5), 1.0),
116
+ 'weightSimplify': hp.lognormal('weightSimplify', np.log(0.05), 1.0),
117
+ 'weightRandomize': hp.lognormal('weightRandomize', np.log(0.25), 1.0),
 
 
 
 
 
118
  }
119
 
120
  ################################################################################
 
196
 
197
  # Merge with empty trials dataset:
198
  save_trials = merge_trials(hyperopt_trial, trials.trials[-n:])
199
+ new_fname = TRIALS_FOLDER + '/' + str(np.random.randint(0, sys.maxsize)) + str(time.time()) + '.pkl'
200
  pkl.dump({'trials': save_trials, 'n': n}, open(new_fname, 'wb'))
201
  loaded_fnames.append(new_fname)
202
 
operators.jl CHANGED
@@ -1,5 +1,6 @@
1
  # Define allowed operators. Any julia operator can also be used.
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;
 
 
1
  # Define allowed operators. Any julia operator can also be used.
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
6
+ loga(x::Float32)::Float32 = log(abs(x) + 1)