@@ -79,6 +79,12 @@ def get_args():
7979 default = 0.0005 ,
8080 help = 'Minimum improvement in validation metric to reset patience (default: %(default)s)' ,
8181 )
82+ parser .add_argument (
83+ '--learning-rate-decay' ,
84+ type = float ,
85+ default = 1 / 3 ,
86+ help = 'Factor to decay learning rate by on plateau (default: %(default)s)' ,
87+ )
8288 parser .add_argument (
8389 '--chunks-per-batch' ,
8490 type = int ,
@@ -279,6 +285,7 @@ def categorical_crossentropy_2d_gene_ml(y_true, y_pred):
279285 best_val_score = - 1.0
280286 best_epoch = 0
281287 patience_counter = 0
288+ decay_counter = 0
282289
283290 # Evaluation batch size can be smaller than training to reduce peak GPU mem
284291 EVAL_BATCH_SIZE = max (1 , min (BATCH_SIZE , args .eval_batch_size * N_GPUS ))
@@ -423,11 +430,20 @@ def print_performance_metrics(indices, max_eval):
423430
424431 # Early stopping: halt if patience exceeded
425432 if args .early_stopping_patience > 0 and patience_counter >= args .early_stopping_patience :
426- tee (f"\n \033 [93mEarly stopping triggered after { patience_counter } evaluations without improvement.\033 [0m" )
427- tee (f"\033 [92mBest epoch: { best_epoch } with validation score: { best_val_score :.4f} \033 [0m" )
428- tee (f"\033 [92mRecommended checkpoint: GeneML{ args .context_length } _c{ args .dataset_name } _ep{ best_epoch } .keras\033 [0m" )
429- h5f .close ()
430- sys .exit (0 )
433+ # allow learning rate to decay up to 2 times before stopping
434+ if decay_counter < 2 :
435+ old_lr = K .get_value (model .optimizer .learning_rate )
436+ new_lr = old_lr * args .learning_rate_decay
437+ K .set_value (model .optimizer .learning_rate , new_lr )
438+ tee (f"\n \033 [93mLearning rate decayed from { old_lr :.5f} to { new_lr :.5f} after { patience_counter } evaluations without improvement.\033 [0m" )
439+ patience_counter = 0
440+ decay_counter += 1
441+ else :
442+ tee (f"\n \033 [93mEarly stopping triggered after { patience_counter } evaluations without improvement.\033 [0m" )
443+ tee (f"\033 [92mBest epoch: { best_epoch } with validation score: { best_val_score :.4f} \033 [0m" )
444+ tee (f"\033 [92mRecommended checkpoint: GeneML{ args .context_length } _c{ args .dataset_name } _ep{ best_epoch } .keras\033 [0m" )
445+ h5f .close ()
446+ sys .exit (0 )
431447 else :
432448 tee (f"Skipping evaluation this epoch (eval_every={ args .eval_every } )" )
433449 tee ("--- %s seconds ---" % (time .time () - start_time ))
0 commit comments