MilesCranmer commited on
Commit
cc2f913
1 Parent(s): a1e142a

Add file to do hyperparam optimization

Browse files
Files changed (1) hide show
  1. hyperopt.py +162 -0
hyperopt.py ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Start a hyperoptimization from a single node"""
2
+ import sys
3
+ import numpy as np
4
+ import pickle as pkl
5
+ import hyperopt
6
+ from hyperopt import hp, fmin, tpe, Trials
7
+ import signal
8
+ import eureqa
9
+
10
+
11
+ #Change the following code to your file
12
+ ################################################################################
13
+ TRIALS_FOLDER = 'trials'
14
+ NUMBER_TRIALS_PER_RUN = 1
15
+
16
+ def run_trial(args):
17
+ """Evaluate the model loss using the hyperparams in args
18
+
19
+ :args: A dictionary containing all hyperparameters
20
+ :returns: Dict with status and loss from cross-validation
21
+
22
+ """
23
+
24
+ for key in 'niterations npop ncyclesperiteration topn'.split(' '):
25
+ args[key] = int(args[key])
26
+
27
+ def handler(signum, frame):
28
+ raise ValueError("Takes too long")
29
+
30
+ signal.signal(signal.SIGALRM, handler)
31
+ maxTime = 60
32
+ ntrials = 1 #3
33
+ equation_file=f'hall_of_fame_{np.random.rand():f}.csv'
34
+ signal.alarm(maxTime)
35
+
36
+ try:
37
+ trials = []
38
+ for i in range(1, 2):
39
+ trials.append([np.min(eureqa.eureqa(
40
+ test=f"simple{i}",
41
+ threads=20,
42
+ binary_operators=["plus", "mult", "pow", "div"],
43
+ unary_operators=["cos", "exp", "sin", "log"],
44
+ equation_file=equation_file,
45
+ **args)['MSE']) for _ in range(ntrials)])
46
+ signal.alarm(0)
47
+ except ValueError:
48
+ return {
49
+ 'status': 'ok', # or 'fail' if nan loss
50
+ 'loss': np.inf
51
+ }
52
+
53
+ loss = np.average(trials)
54
+
55
+ return {
56
+ 'status': 'ok', # or 'fail' if nan loss
57
+ 'loss': loss
58
+ }
59
+
60
+
61
+ space = {
62
+ 'niterations': hp.qloguniform('niterations', np.log(10), 0.5, 1),
63
+ 'npop': hp.qloguniform('npop', np.log(100), 0.5, 1),
64
+ 'ncyclesperiteration': hp.qloguniform('ncyclesperiteration', np.log(5000), 0.5, 1),
65
+ 'topn': hp.quniform('topn', 1, 30, 1),
66
+ 'annealing': hp.choice('annealing', [False, True]),
67
+ 'alpha': hp.lognormal('alpha', np.log(10.0), 0.5),
68
+ 'parsimony': hp.lognormal('parsimony', np.log(1e-3), 0.5),
69
+ 'fractionReplacedHof': hp.lognormal('fractionReplacedHof', np.log(0.1), 0.5),
70
+ 'fractionReplaced': hp.lognormal('fractionReplaced', np.log(0.1), 0.5),
71
+ 'weightMutateConstant': hp.lognormal('weightMutateConstant', np.log(4.0), 0.5),
72
+ 'weightMutateOperator': hp.lognormal('weightMutateOperator', np.log(0.5), 0.5),
73
+ 'weightAddNode': hp.lognormal('weightAddNode', np.log(0.5), 0.5),
74
+ 'weightDeleteNode': hp.lognormal('weightDeleteNode', np.log(0.5), 0.5),
75
+ 'weightSimplify': hp.lognormal('weightSimplify', np.log(0.05), 0.5),
76
+ 'weightRandomize': hp.lognormal('weightRandomize', np.log(0.25), 0.5),
77
+ 'weightDoNothing': hp.lognormal('weightDoNothing', np.log(1.0), 0.5),
78
+ }
79
+
80
+ ################################################################################
81
+
82
+
83
+
84
+ def merge_trials(trials1, trials2_slice):
85
+ """Merge two hyperopt trials objects
86
+
87
+ :trials1: The primary trials object
88
+ :trials2_slice: A slice of the trials object to be merged,
89
+ obtained with, e.g., trials2.trials[:10]
90
+ :returns: The merged trials object
91
+
92
+ """
93
+ max_tid = 0
94
+ if len(trials1.trials) > 0:
95
+ max_tid = max([trial['tid'] for trial in trials1.trials])
96
+
97
+ for trial in trials2_slice:
98
+ tid = trial['tid'] + max_tid + 1
99
+ hyperopt_trial = Trials().new_trial_docs(
100
+ tids=[None],
101
+ specs=[None],
102
+ results=[None],
103
+ miscs=[None])
104
+ hyperopt_trial[0] = trial
105
+ hyperopt_trial[0]['tid'] = tid
106
+ hyperopt_trial[0]['misc']['tid'] = tid
107
+ for key in hyperopt_trial[0]['misc']['idxs'].keys():
108
+ hyperopt_trial[0]['misc']['idxs'][key] = [tid]
109
+ trials1.insert_trial_docs(hyperopt_trial)
110
+ trials1.refresh()
111
+ return trials1
112
+
113
+ loaded_fnames = []
114
+ trials = None
115
+ # Run new hyperparameter trials until killed
116
+ while True:
117
+ np.random.seed()
118
+
119
+ # Load up all runs:
120
+ import glob
121
+ path = TRIALS_FOLDER + '/*.pkl'
122
+ for fname in glob.glob(path):
123
+ if fname in loaded_fnames:
124
+ continue
125
+
126
+ trials_obj = pkl.load(open(fname, 'rb'))
127
+ n_trials = trials_obj['n']
128
+ trials_obj = trials_obj['trials']
129
+ if len(loaded_fnames) == 0:
130
+ trials = trials_obj
131
+ else:
132
+ print("Merging trials")
133
+ trials = merge_trials(trials, trials_obj.trials[-n_trials:])
134
+
135
+ loaded_fnames.append(fname)
136
+
137
+ print("Loaded trials", len(loaded_fnames))
138
+ if len(loaded_fnames) == 0:
139
+ trials = Trials()
140
+
141
+ n = NUMBER_TRIALS_PER_RUN
142
+ try:
143
+ best = fmin(run_trial,
144
+ space=space,
145
+ algo=tpe.suggest,
146
+ max_evals=n + len(trials.trials),
147
+ trials=trials,
148
+ verbose=1,
149
+ rstate=np.random.RandomState(np.random.randint(1,10**6))
150
+ )
151
+ except hyperopt.exceptions.AllTrialsFailed:
152
+ continue
153
+
154
+ print('current best', best)
155
+ hyperopt_trial = Trials()
156
+
157
+ # Merge with empty trials dataset:
158
+ save_trials = merge_trials(hyperopt_trial, trials.trials[-n:])
159
+ new_fname = TRIALS_FOLDER + '/' + str(np.random.randint(0, sys.maxsize)) + '.pkl'
160
+ pkl.dump({'trials': save_trials, 'n': n}, open(new_fname, 'wb'))
161
+ loaded_fnames.append(new_fname)
162
+