-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop' of github.com:ECP-CANDLE/Benchmarks into develop
- Loading branch information
Showing
6 changed files
with
631 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
from tensorflow.keras.callbacks import * | ||
from tensorflow.keras import backend as K | ||
import numpy as np | ||
|
||
class CyclicLR(Callback): | ||
"""This callback implements a cyclical learning rate policy (CLR). | ||
The method cycles the learning rate between two boundaries with | ||
some constant frequency, as detailed in this paper (https://arxiv.org/abs/1506.01186). | ||
The amplitude of the cycle can be scaled on a per-iteration or | ||
per-cycle basis. | ||
This class has three built-in policies, as put forth in the paper. | ||
"triangular": | ||
A basic triangular cycle w/ no amplitude scaling. | ||
"triangular2": | ||
A basic triangular cycle that scales initial amplitude by half each cycle. | ||
"exp_range": | ||
A cycle that scales initial amplitude by gamma**(cycle iterations) at each | ||
cycle iteration. | ||
For more detail, please see paper. | ||
# Example | ||
```python | ||
clr = CyclicLR(base_lr=0.001, max_lr=0.006, | ||
step_size=2000., mode='triangular') | ||
model.fit(X_train, Y_train, callbacks=[clr]) | ||
``` | ||
Class also supports custom scaling functions: | ||
```python | ||
clr_fn = lambda x: 0.5*(1+np.sin(x*np.pi/2.)) | ||
clr = CyclicLR(base_lr=0.001, max_lr=0.006, | ||
step_size=2000., scale_fn=clr_fn, | ||
scale_mode='cycle') | ||
model.fit(X_train, Y_train, callbacks=[clr]) | ||
``` | ||
# Arguments | ||
base_lr: initial learning rate which is the | ||
lower boundary in the cycle. | ||
max_lr: upper boundary in the cycle. Functionally, | ||
it defines the cycle amplitude (max_lr - base_lr). | ||
The lr at any cycle is the sum of base_lr | ||
and some scaling of the amplitude; therefore | ||
max_lr may not actually be reached depending on | ||
scaling function. | ||
step_size: number of training iterations per | ||
half cycle. Authors suggest setting step_size | ||
2-8 x training iterations in epoch. | ||
mode: one of {triangular, triangular2, exp_range}. | ||
Default 'triangular'. | ||
Values correspond to policies detailed above. | ||
If scale_fn is not None, this argument is ignored. | ||
gamma: constant in 'exp_range' scaling function: | ||
gamma**(cycle iterations) | ||
scale_fn: Custom scaling policy defined by a single | ||
argument lambda function, where | ||
0 <= scale_fn(x) <= 1 for all x >= 0. | ||
mode paramater is ignored | ||
scale_mode: {'cycle', 'iterations'}. | ||
Defines whether scale_fn is evaluated on | ||
cycle number or cycle iterations (training | ||
iterations since start of cycle). Default is 'cycle'. | ||
""" | ||
|
||
def __init__(self, base_lr=0.001, max_lr=0.006, step_size=2000., mode='triangular', | ||
gamma=1., scale_fn=None, scale_mode='cycle'): | ||
super(CyclicLR, self).__init__() | ||
|
||
self.base_lr = base_lr | ||
self.max_lr = max_lr | ||
self.step_size = step_size | ||
self.mode = mode | ||
self.gamma = gamma | ||
if scale_fn == None: | ||
if self.mode == 'triangular': | ||
self.scale_fn = lambda x: 1. | ||
self.scale_mode = 'cycle' | ||
elif self.mode == 'triangular2': | ||
self.scale_fn = lambda x: 1/(2.**(x-1)) | ||
self.scale_mode = 'cycle' | ||
elif self.mode == 'exp_range': | ||
self.scale_fn = lambda x: gamma**(x) | ||
self.scale_mode = 'iterations' | ||
else: | ||
self.scale_fn = scale_fn | ||
self.scale_mode = scale_mode | ||
self.clr_iterations = 0. | ||
self.trn_iterations = 0. | ||
self.history = {} | ||
|
||
self._reset() | ||
|
||
def _reset(self, new_base_lr=None, new_max_lr=None, | ||
new_step_size=None): | ||
"""Resets cycle iterations. | ||
Optional boundary/step size adjustment. | ||
""" | ||
if new_base_lr != None: | ||
self.base_lr = new_base_lr | ||
if new_max_lr != None: | ||
self.max_lr = new_max_lr | ||
if new_step_size != None: | ||
self.step_size = new_step_size | ||
self.clr_iterations = 0. | ||
|
||
def clr(self): | ||
cycle = np.floor(1+self.clr_iterations/(2*self.step_size)) | ||
x = np.abs(self.clr_iterations/self.step_size - 2*cycle + 1) | ||
if self.scale_mode == 'cycle': | ||
return self.base_lr + (self.max_lr-self.base_lr)*np.maximum(0, (1-x))*self.scale_fn(cycle) | ||
else: | ||
return self.base_lr + (self.max_lr-self.base_lr)*np.maximum(0, (1-x))*self.scale_fn(self.clr_iterations) | ||
|
||
def on_train_begin(self, logs={}): | ||
logs = logs or {} | ||
|
||
if self.clr_iterations == 0: | ||
K.set_value(self.model.optimizer.lr, self.base_lr) | ||
else: | ||
K.set_value(self.model.optimizer.lr, self.clr()) | ||
|
||
def on_batch_end(self, epoch, logs=None): | ||
|
||
logs = logs or {} | ||
self.trn_iterations += 1 | ||
self.clr_iterations += 1 | ||
|
||
self.history.setdefault('lr', []).append(K.get_value(self.model.optimizer.lr)) | ||
self.history.setdefault('iterations', []).append(self.trn_iterations) | ||
|
||
for k, v in logs.items(): | ||
self.history.setdefault(k, []).append(v) | ||
|
||
K.set_value(self.model.optimizer.lr, self.clr()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#!/bin/bash | ||
#PBS -N st_hvd | ||
#PBS -l select=2 | ||
#PBS -l walltime=24:00:00 | ||
#PBS -q preemptable | ||
#PBS -l filesystems=grand | ||
#PBS -A datascience | ||
#PBS -o logs/ | ||
#PBS -e logs/ | ||
#PBS -m abe | ||
#PBS -M [email protected] | ||
|
||
DATA_PATH=/grand/datascience/avasan/ST_Benchmarks/Data/1M-flatten | ||
|
||
TFIL=ml.3CLPro_7BQY_A_1_F.Orderable_zinc_db_enaHLL.sorted.4col.dd.parquet.xform-smiles.csv.reg.train | ||
VFIL=ml.3CLPro_7BQY_A_1_F.Orderable_zinc_db_enaHLL.sorted.4col.dd.parquet.xform-smiles.csv.reg.val | ||
|
||
EP=400 | ||
NUMHEAD=16 | ||
DR_TB=0.1 | ||
DR_ff=0.1 | ||
|
||
ACT=elu | ||
DROP=False | ||
LR=0.0000025 | ||
LOSS=mean_squared_error | ||
HVDSWITCH=True | ||
|
||
if [$HVDSWITCH = False]; then | ||
python smiles_regress_transformer_run_hvd.py --in_train ${DATA_PATH}/${TFIL} --in_vali ${DATA_PATH}/${VFIL} --ep $EP --num_heads $NUMHEAD --DR_TB $DR_TB --DR_ff $DR_ff --activation $ACT --drop_post_MHA $DROP --lr $LR --loss_fn $LOSS --hvd_switch $HVDSWITCH | ||
|
||
else | ||
NP=8 | ||
PPN=4 | ||
OUT=logfile.log | ||
mpiexec --np $NP -ppn $PPN --cpu-bind verbose,list:0,1,2,3,4,5,6,7 -env NCCL_COLLNET_ENABLE=1 -env NCCL_NET_GDR_LEVEL=PHB python smiles_regress_transformer_run_hvd.py --in_train ${DATA_PATH}/${TFIL} --in_vali ${DATA_PATH}/${VFIL} --ep $EP --num_heads $NUMHEAD --DR_TB $DR_TB --DR_ff $DR_ff --activation $ACT --drop_post_MHA $DROP --lr $LR --loss_fn $LOSS --hvd_switch $HVDSWITCH > $OUT | ||
|
||
fi | ||
|
Oops, something went wrong.