File size: 15,332 Bytes
22b374f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
import random
import optuna
import numpy as np

## change default to "selector" for that parameter
## there are specifications for what type should be there, see that and do final design. FOr exxample --> learning_rate (Union[float, Callable[[float], float]])
## Fix TENSORBOARD_LOG
## Generate a number/code that is unique to each hyperparmeter configuration



# import stable_baselines3.common.schedules as schedules



#####################################################################
##             LEARNING RATE SCHEDULER (learning_rate)             ##
#####################################################################
# Currently random, make it categorical and pass parameters using dictionary properly

class Learning_Rate_Scheduler:
    # remove this default function later
    # Make this categorical
    # send params in __init__ for all class's functions --> def __init__(self, i, params):
    # always call through 
    

    def __init__(self):
        self.low = 1e-5
        self.high = 1e-2
        self.log = True
        #do this for all
    
    def default(self):
        return random.random() / 1000

    def opt(self, trial):
        return trial.suggest_float("learning_rate", self.low, self.high, log=self.log)

    def step_decay(optimizer, initial_lr=0.001, drop_rate=0.1, epochs_drop=10):
        return
        scheduler = lr_scheduler.StepLR(optimizer, step_size=epochs_drop, gamma=drop_rate)
        return scheduler

    def exp_decay(optimizer, initial_lr=0.001, decay_rate=0.96):
        return
        scheduler = lr_scheduler.ExponentialLR(optimizer, gamma=decay_rate)
        return scheduler

    def cosine_anneal(optimizer, initial_lr=0.001, epochs=100):
        return
        scheduler = lr_scheduler.CosineAnnealingLR(optimizer, T_max=epochs)
        return scheduler

    def reduce_on_plateau(optimizer, mode='min', factor=0.1, patience=10, verbose=False):
        return
        scheduler = lr_scheduler.ReduceLROnPlateau(optimizer, mode=mode, factor=factor, patience=patience, verbose=verbose)
        return scheduler

    def cyclical_lr(optimizer, step_size=2000, base_lr=1e-3, max_lr=6e-3, mode='triangular', gamma=1.):
        return
        scheduler = lr_scheduler.CyclicLR(optimizer, base_lr=base_lr, max_lr=max_lr, step_size_up=step_size,
                                        mode=mode, gamma=gamma)
        return scheduler

    def warmup_lr(optimizer, factor=10, warmup_epochs=5):
        return
        def lr_lambda(current_epoch):
            if current_epoch < warmup_epochs:
                return factor
            else:
                return 1.0
        scheduler = lr_scheduler.LambdaLR(optimizer, lr_lambda)
        return scheduler

    def one_cycle_lr(optimizer, num_steps, lr_range=(1e-4, 1e-2), momentum_range=(0.85, 0.95)):
        return
        scheduler = lr_scheduler.OneCycleLR(optimizer, max_lr=lr_range[1], total_steps=num_steps,
                                            pct_start=0.3, anneal_strategy='cos', cycle_momentum=True,
                                            base_momentum=momentum_range[0], max_momentum=momentum_range[1])
        return scheduler

    def constant_schedule(self, lr=3e-4):
        return schedules.constant_schedule(3e-4)

    def linear_schedule(self, initial_value=1e6, final_value=3e-4, n_timsteps=1e-4):
        return schedules.linear_schedule(initial_value, final_value, n_timsteps)

    def piecewise_schedule(self, schedule_pieces):
        return schedules.piecewise_schedule(schedule_pieces)

    def cosine_schedule(self, initial_lr=3e-4, final_lr=1e-4, total_timesteps=1e6): # check if this cosine annealing
        return schedules.cosine_schedule(initial_lr, final_lr, total_timesteps)

    def linear_warmup_schedule(self):
        warmup_timesteps = 1e5
        learning_rate_schedule = schedules.linear_schedule(9e5, 0, 3e-4)
        learning_rate = schedules.linear_warmup(learning_rate_schedule, warmup_timesteps, 0)
        return learning_rate

    def combined_scheduler(self):
        pass



#####################################################################
##                        POLICY(policy)                           ##
#####################################################################
# Categorical
class PolicySelector:
    def __init__(self):
        pass

    def opt(self, trial):
        return "MlpPolicy"
        
    def default(self):
        return self.MlpPolicy()

    def MlpPolicy(self):
        return "MlpPolicy"
    
    def CnnPolicy(self):
        return "CnnPolicy"

    def MultiInputPolicy(self):
        return "MultiInputPolicy"
    

#####################################################################
##                  UPDATE PER STEPS (n_steps)                     ##
#####################################################################
#Refine the search space --> dont just do 2^i in between also there might be peak

class StepsPerUpdate:
    
    def __init__(self):
        self.max_size = 2048

        pass

    def opt(self, trial):
        return 2 ** trial.suggest_int("n_steps", 10, 12)

    def default(self):
        return random.randint(1, self.max_size)

#####################################################################
##                      BATCH SIZE (batch_size)                    ##
#####################################################################

class BatchSize:
    def __init__(self):
        self.max_size = 64
        pass

    def opt(self, trial):
        return 2 ** trial.suggest_int("batch_size", 5, 8)
    
    def default(self):
        self.max_size=26
        return random.randint(1, self.max_size)

#####################################################################
##    No. OF EPOCHS WHEN OPTIMIZING SURROGATE LOSS (n_epochs)      ##
#####################################################################
# Higher the better

class NoOfEpochs:
    def __init__(self):
        self.max_size = 10
        pass

    def opt(self, trial):
        return trial.suggest_int("n_epochs", 5, 10)
    
    def default(self):
        return random.randint(1, self.max_size)


#####################################################################
##                      DISCOUNT FACTOR (gamma)                    ##
#####################################################################

class DiscountFactor:
    def __init__(self):
        self.max_size = 10
    
    def opt(self, trial):
        return trial.suggest_float("gamma", 0.9, 0.999)
    
    def default(self):
        return random.random()

#####################################################################
##    BIAS-VARIANCE TRADEOFF for GENERALIZED ADVANTAGE ESTIMATOR   ##
#####################################################################

class BiasVarianceTradeoff:
    def __init__(self):
        pass

    def opt(self, trial):
        return trial.suggest_float("bvtradeoff", 0.9, 0.99)
    
    def default(self):
        return random.random()

#####################################################################
##                  CLIPPING FUNCTION (clip_range)                 ##
#####################################################################
# Can be a function of progress

class ClipRange:
    def __init__(self):
        pass

    def opt(self, trial):
        return trial.suggest_float("clip_range", 0.1, 0.3)
    
    def default(self):
        return random.random()


#####################################################################
##       CLIPPING RANGE for Value Function (clip_range_vf)         ##
#####################################################################

class ClipRangeVF:
    def __init__(self):
        pass

    def opt(self, trial):
        return trial.suggest_float("clip_range_vf", 0.1, 0.3)
    
    def default(self):
        return random.random()


#####################################################################
##             NORMALIZE ADVANTAGE(normalize_advantage)            ##
#####################################################################

class NormalizeAdvantage:
    def __init__(self):
        pass
    
    def opt(self, trial):
        return False

    def default(self):
        return True


#####################################################################
##                  ENTROPY COEFFICIENT (ent_coef)                 ##
#####################################################################

class EntropyCoefficient:
    def __init__(self):
        pass

    def opt(self, trial):
        return trial.suggest_float("ent_coef", 0, 0.01)
    
    def default(self):
        return 0


#####################################################################
##            VALUE FUNCTION COEFFICIENT (vf_coef)                 ##
#####################################################################

class ValueFunctionCoefficient:
    def __init__(self):
        pass

    def opt(self, trial):
        return trial.suggest_float("vf_coef", 0.25, 0.75)
    
    def default(self):
        return 0.5

#####################################################################
##       MAXIMUM VALUE for Gradient Clipping (max_grad_norm)       ##
#####################################################################

class MaxGradNorm:
    def __init__(self):
        pass

    def opt(self, trial):
        return trial.suggest_float("max_grad_norm", 0.3, 1)
    
    def default(self):
        return 0.5


#####################################################################
##        USE ? Generalized State Dependent Exploration            ##
#####################################################################

class BoolGeneralizedStateDependentExploration:
    def __init__(self):
        pass

    def opt(self, trial):
        return False
    
    def default(self):
        return False


#####################################################################
##             SAMPLE NEW NOISE MATRIX(sde_sample_freq)            ##
#####################################################################

class SDESampleFrequency:
    def __init__(self):
        pass

    def opt(self, trial):
        return -1
    
    def default(self):
        return -1


#####################################################################
##                LIMIT KL-Divergence (target_kl)                  ##
#####################################################################

class TargetKL:
    def __init__(self):
        pass

    def opt(self, trial):
        return trial.suggest_float("target_kl", 0.01, 0.05)
    
    def default(self):
        return None


#####################################################################
##                      TENSORBOARD_LOG                            ##
#####################################################################

# class TensorBoardLog:
#     def __init__(self):
#         pass

#     def opt(self, trial):
#         return 
    
#     def default(self):
#         return None


#####################################################################
##                   POLICY_KWARGS (policy_kwargs)                 ##
#####################################################################

class PolicyKWargs:
    def __init__(self):
        pass

    def opt(self, trial):
        return None
    
    def default(self):
        return None


#####################################################################
##                           SEED (seed)                           ##
#####################################################################

class Seed:
    def __init__(self):
        pass

    def opt(self, trial):
        return trial.suggest_int("seed", 1, 10)
    
    def default(self):
        return None


all_policy = [
    "MlpPolicy",
    "CnnPolicy",
    "MultiInputPolicy",
]

# ~!@ environment is fixed {maybe we can find stronger relations between hyperparameters across other environments}
    # Very important idea


all_classes_in_this_file = [
    'BatchSize',
    'BiasVarianceTradeoff',
    'BoolGeneralizedStateDependentExploration',
    'ClipRange',
     'ClipRangeVF',
      'DiscountFactor',
       'EntropyCoefficient',
        'Learning_Rate_Scheduler',
         'MaxGradNorm',
          'MegaHandler',
           'NoOfEpochs',
            'NormalizeAdvantage',
             'PolicyKWargs',
              'PolicySelector',
               'SDESampleFrequency',
                'Seed',
                 'StepsPerUpdate',
                  'TargetKL',
                   'TensorBoardLog',
                    'ValueFunctionCoefficient'
]

def request_next_HypConfig(env, tb_logs):
    hyps = dict()

    hyps["policy"] = PolicySelector().default()
    hyps["env"] = env
    hyps["learning_rate"] = Learning_Rate_Scheduler().default()
    hyps["n_steps"] = StepsPerUpdate().default()
    hyps["batch_size"] = BatchSize().default()
    hyps["n_epochs"] = NoOfEpochs().default()
    hyps["gamma"] = DiscountFactor().default()
    hyps["gae_lambda"] = BiasVarianceTradeoff().default()
    hyps["clip_range"] = ClipRange().default()
    hyps["clip_range_vf"] = ClipRangeVF().default()
    hyps["normalize_advantage"] = NormalizeAdvantage().default()
    hyps["ent_coef"] = EntropyCoefficient().default()
    hyps["vf_coef"] = ValueFunctionCoefficient().default()
    hyps["max_grad_norm"] = MaxGradNorm().default()
    hyps["use_sde"] = BoolGeneralizedStateDependentExploration().default()
    hyps["sde_sample_freq"] = SDESampleFrequency().default()
    hyps["target_kl"] = TargetKL().default()
    hyps["tensorboard_log"] = tb_logs
    hyps["policy_kwargs"] = PolicyKWargs().default()
    hyps["verbose"] = 0
    hyps["seed"] = Seed().default()
    hyps["device"] = 'auto'
    hyps["_init_setup_model"] = True

    return hyps





#####################################################################
##            MEGA HANDLER (handler of all classes below)          ##
#####################################################################
class MegaHandler:
    def __init__(slef):
        pass

    def request_next_HypConfig(self, trial, env, tb_logs):
        hyps = dict()

        hyps["policy"] = PolicySelector().opt(trial)
        hyps["env"] = env
        hyps["learning_rate"] = Learning_Rate_Scheduler().opt(trial)
        hyps["n_steps"] = StepsPerUpdate().opt(trial)
        hyps["batch_size"] = BatchSize().opt(trial)
        hyps["n_epochs"] = NoOfEpochs().opt(trial)
        hyps["gamma"] = DiscountFactor().opt(trial)
        hyps["gae_lambda"] = BiasVarianceTradeoff().opt(trial)
        hyps["clip_range"] = ClipRange().opt(trial)
        hyps["clip_range_vf"] = ClipRangeVF().opt(trial)
        hyps["normalize_advantage"] = NormalizeAdvantage().opt(trial)
        hyps["ent_coef"] = EntropyCoefficient().opt(trial)
        hyps["vf_coef"] = ValueFunctionCoefficient().opt(trial)
        hyps["max_grad_norm"] = MaxGradNorm().opt(trial)
        hyps["use_sde"] = BoolGeneralizedStateDependentExploration().opt(trial)
        hyps["sde_sample_freq"] = SDESampleFrequency().opt(trial)
        hyps["target_kl"] = TargetKL().opt(trial)
        hyps["tensorboard_log"] = tb_logs
        hyps["policy_kwargs"] = PolicyKWargs().opt(trial)
        hyps["verbose"] = 0
        hyps["seed"] = 1
        hyps["device"] = 'auto'
        hyps["_init_setup_model"] = True

        return hyps