Support any lr_scheduler

This commit is contained in:
Phuc Le
2019-07-26 11:03:44 +07:00
parent c4b37d1efe
commit 7d97e3e6e4
9 changed files with 20 additions and 41 deletions
-1
View File
@@ -264,7 +264,6 @@ tensorboard --logdir /some/path
###### Training loop
- [Accumulate gradients](https://williamfalcon.github.io/pytorch-lightning/Trainer/Training%20Loop/#accumulated-gradients)
- [Anneal Learning rate](https://williamfalcon.github.io/pytorch-lightning/Trainer/Training%20Loop/#anneal-learning-rate)
- [Force training for min or max epochs](https://williamfalcon.github.io/pytorch-lightning/Trainer/Training%20Loop/#force-training-for-min-or-max-epochs)
- [Force disable early stop](https://williamfalcon.github.io/pytorch-lightning/Trainer/Training%20Loop/#force-disable-early-stop)
- [Gradient Clipping](https://williamfalcon.github.io/pytorch-lightning/Trainer/Training%20Loop/#gradient-clipping)
@@ -222,26 +222,27 @@ def validation_end(self, outputs):
def configure_optimizers(self)
```
Set up as many optimizers as you need. Normally you'd need one. But in the case of GANs or something more esoteric you might have multiple.
Lightning will call .backward() and .step() on each one. If you use 16 bit precision it will also handle that.
Set up as many optimizers and (optionally) learning rate schedulers as you need. Normally you'd need one. But in the case of GANs or something more esoteric you might have multiple.
Lightning will call .backward() and .step() on each one in every epoch. If you use 16 bit precision it will also handle that.
##### Return
List - List of optimizers
Tuple - List of optimizers and list of schedulers
**Example**
``` {.python}
# most cases
def configure_optimizers(self):
opt = Adam(lr=0.01)
return [opt]
opt = Adam(self.model.parameters(), lr=0.01)
return [opt], []
# gan example
# gan example, with scheduler for discriminator
def configure_optimizers(self):
generator_opt = Adam(lr=0.01)
disriminator_opt = Adam(lr=0.02)
return [generator_opt, disriminator_opt]
generator_opt = Adam(self.model_gen.parameters(), lr=0.01)
disriminator_opt = Adam(self.model_disc.parameters(), lr=0.02)
discriminator_sched = CosineAnnealing(discriminator_opt, T_max=10)
return [generator_opt, disriminator_opt], [discriminator_sched]
```
---
@@ -427,4 +428,4 @@ def add_model_specific_args(parent_parser, root_dir):
parser.opt_list('--batch_size', default=256, type=int, options=[32, 64, 128, 256], tunable=False)
parser.opt_list('--optimizer_name', default='adam', type=str, options=['adam'], tunable=False)
return parser
```
```
-11
View File
@@ -11,17 +11,6 @@ Accumulated gradients runs K small batches of size N before doing a backwards pa
trainer = Trainer(accumulate_grad_batches=1)
```
---
#### Anneal Learning rate
Cut the learning rate by 10 at every epoch listed in this list.
``` {.python}
# DEFAULT (don't anneal)
trainer = Trainer(lr_scheduler_milestones=None)
# cut LR by 10 at 100, 200, and 300 epochs
trainer = Trainer(lr_scheduler_milestones='100, 200, 300')
```
---
#### Force training for min or max epochs
It can be useful to force training for a minimum number of epochs or limit to a max number
-1
View File
@@ -59,7 +59,6 @@ But of course the fun is in all the advanced things it can do:
**Training loop**
- [Accumulate gradients](Training%20Loop/#accumulated-gradients)
- [Anneal Learning rate](Training%20Loop/#anneal-learning-rate)
- [Force training for min or max epochs](Training%20Loop/#force-training-for-min-or-max-epochs)
- [Force disable early stop](Training%20Loop/#force-disable-early-stop)
- [Use multiple optimizers (like GANs)](../Pytorch-lightning/LightningModule/#configure_optimizers)
-1
View File
@@ -60,7 +60,6 @@ To start a new project define these two files.
###### Training loop
- [Accumulate gradients](https://williamfalcon.github.io/pytorch-lightning/Trainer/Training%20Loop/#accumulated-gradients)
- [Anneal Learning rate](https://williamfalcon.github.io/pytorch-lightning/Trainer/Training%20Loop/#anneal-learning-rate)
- [Force training for min or max epochs](https://williamfalcon.github.io/pytorch-lightning/Trainer/Training%20Loop/#force-training-for-min-or-max-epochs)
- [Force disable early stop](https://williamfalcon.github.io/pytorch-lightning/Trainer/Training%20Loop/#force-disable-early-stop)
- [Gradient Clipping](https://williamfalcon.github.io/pytorch-lightning/Trainer/Training%20Loop/#gradient-clipping)
@@ -174,7 +174,8 @@ class LightningTemplateModel(LightningModule):
:return: list of optimizers
"""
optimizer = optim.Adam(self.parameters(), lr=self.hparams.learning_rate)
return [optimizer]
scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=10)
return [optimizer], [scheduler]
def __dataloader(self, train):
# init data generators
@@ -231,7 +232,6 @@ class LightningTemplateModel(LightningModule):
# parser.set_defaults(gradient_clip=5.0)
# network params
parser.opt_list('--drop_prob', default=0.2, options=[0.2, 0.5], type=float, tunable=False)
parser.add_argument('--in_features', default=28*28, type=int)
parser.add_argument('--out_features', default=10, type=int)
parser.add_argument('--hidden_dim', default=50000, type=int) # use 500 for CPU, 50000 for GPU to see speed difference
@@ -128,12 +128,13 @@ class ExampleModel1(LightningModule):
# ---------------------
def configure_optimizers(self):
"""
return whatever optimizers we want here
return whatever optimizers and (optionally) schedulers we want here
:return: list of optimizers
"""
optimizer = self.choose_optimizer(self.hparams.optimizer_name, self.parameters(), {'lr': self.hparams.learning_rate}, 'optimizer')
self.optimizers = [optimizer]
return self.optimizers
self.schedulers = []
return self.optimizers, self.schedulers
def __dataloader(self, train):
# init data generators
+3 -12
View File
@@ -71,7 +71,6 @@ class Trainer(TrainerIO):
train_percent_check=1.0, val_percent_check=1.0, test_percent_check=1.0,
val_check_interval=0.95,
log_save_interval=100, add_log_row_interval=10,
lr_scheduler_milestones=None,
distributed_backend='dp',
use_amp=False,
print_nan_grads=False,
@@ -104,7 +103,6 @@ class Trainer(TrainerIO):
:param val_check_interval:
:param log_save_interval:
:param add_log_row_interval:
:param lr_scheduler_milestones:
:param distributed_backend: 'np' to use DistributedParallel, 'ddp' to use DistributedDataParallel
:param use_amp:
:param print_nan_grads:
@@ -141,7 +139,6 @@ class Trainer(TrainerIO):
self.early_stop_callback = early_stop_callback
self.min_nb_epochs = min_nb_epochs
self.nb_sanity_val_steps = nb_sanity_val_steps
self.lr_scheduler_milestones = [] if lr_scheduler_milestones is None else [int(x.strip()) for x in lr_scheduler_milestones.split(',')]
self.lr_schedulers = []
self.amp_level = amp_level
self.print_nan_grads = print_nan_grads
@@ -444,7 +441,7 @@ class Trainer(TrainerIO):
# CHOOSE OPTIMIZER
# filter out the weights that were done on gpu so we can load on good old cpus
self.optimizers = model.configure_optimizers()
self.optimizers, self.lr_schedulers = model.configure_optimizers()
self.__run_pretrain_routine(model)
@@ -456,7 +453,7 @@ class Trainer(TrainerIO):
# CHOOSE OPTIMIZER
# filter out the weights that were done on gpu so we can load on good old cpus
self.optimizers = model.configure_optimizers()
self.optimizers, self.lr_schedulers = model.configure_optimizers()
model.cuda(self.data_parallel_device_ids[0])
@@ -507,7 +504,7 @@ class Trainer(TrainerIO):
# CHOOSE OPTIMIZER
# filter out the weights that were done on gpu so we can load on good old cpus
self.optimizers = model.configure_optimizers()
self.optimizers, self.lr_schedulers = model.configure_optimizers()
# MODEL
# copy model to each gpu
@@ -587,12 +584,6 @@ class Trainer(TrainerIO):
# init training constants
self.__layout_bookeeping()
# add lr schedulers
if self.lr_scheduler_milestones is not None:
for optimizer in self.optimizers:
scheduler = MultiStepLR(optimizer, self.lr_scheduler_milestones)
self.lr_schedulers.append(scheduler)
# print model summary
if self.proc_rank == 0 and self.print_weights_summary:
ref_model.summarize()
+1 -1
View File
@@ -58,7 +58,7 @@ class LightningModule(GradInformation, ModelIO, ModelHooks):
def configure_optimizers(self):
"""
Return array of optimizers
Return a list of optimizers and a list of schedulers (could be empty)
:return:
"""
raise NotImplementedError