Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update LR schedulers only when their corresponding Optimizer is being… #4868

Merged
merged 36 commits into from
May 4, 2021

Conversation

hemildesai
Copy link
Contributor

@hemildesai hemildesai commented Nov 26, 2020

… used.

In the case when optimizer frequencies are specified,
the LR scheduler corresponding to a particular optimizer is updated
only when that optimizer is being used in the training loop or epoch.

What does this PR do?

Fixes #4815

Also updates several old tests to use BoringModel

Before submitting

  • Was this discussed/approved via a Github issue? (no need for typos and docs improvements)
  • Did you read the contributor guideline, Pull Request section?
  • Did you make sure your PR does only one thing, instead of bundling different changes together? Otherwise, we ask you to create a separate PR for every change.
  • Did you make sure to update the documentation with your changes?
  • Did you write any new necessary tests?
  • Did you verify new and existing tests pass locally with your changes?
  • If you made a notable change (that affects users), did you update the CHANGELOG?

PR review

  • Is this pull request ready for review? (if not, please submit in draft mode)
  • Check that all items from Before submitting are resolved
  • Make sure the title is self-explanatory and the description concisely explains the PR
  • Add labels and milestones (and optionally projects) to the PR so it can be classified; Bugfixes should be including in bug-fix release milestones (m.f.X) and features should be included in (m.X.b) releases.

@pep8speaks
Copy link

pep8speaks commented Nov 26, 2020

Hello @hemildesai! Thanks for updating this PR.

Line 51:13: W503 line break before binary operator

Comment last updated at 2021-05-04 00:57:35 UTC

@codecov
Copy link

codecov bot commented Nov 26, 2020

Codecov Report

Merging #4868 (f1fab63) into master (c6a171b) will decrease coverage by 6%.
The diff coverage is 100%.

@@           Coverage Diff           @@
##           master   #4868    +/-   ##
=======================================
- Coverage      91%     85%    -6%     
=======================================
  Files         200     200            
  Lines       12894   13252   +358     
=======================================
- Hits        11783   11312   -471     
- Misses       1111    1940   +829     

@rohitgr7
Copy link
Contributor

what if I set:

def configure_optimizer(self):
    optimizer1 = {'optimizer': SGD, 'frequency': 10}
    optimizer2 = {'optimizer': ADAM, 'frequency': 10}
    scheduler1 = scheduler(optimizer1)
    scheduler2 = scheduler(optimizer2)
    return [optimizer1, optimizer2], [scheduler1, scheduler2]

the fix won't work, right?

@hemildesai
Copy link
Contributor Author

hemildesai commented Nov 26, 2020

@rohitgr7 It mentions in the docs at https://pytorch-lightning.readthedocs.io/en/stable/lightning_module.html#configure-optimizers that if multiple optimizers are passed in a list, all of them will run at each optimization step. So I assumed that we don't want to change that behavior.

@rohitgr7
Copy link
Contributor

rohitgr7 commented Nov 26, 2020

There is a difference between passing multiple optimizers in a list, and passing multiple optimizers in
dictionaries with a frequency of 1: In the former case, all optimizers will operate on the given batch in
each optimization step. In the latter, only one optimizer will operate on the given batch at every step.

I did pass them in a dictionary within a list with a specified frequency. My concern here is the optimizer will update correctly as per the frequency, but I am concerned that lr_scheduler won't follow.

@hemildesai
Copy link
Contributor Author

hemildesai commented Nov 26, 2020

@rohitgr7 I think the example will error out in the current version as well because when two lists are passed, it assumes that each element of the first list is an optimizer from torch.optim. Although there's no explicit check for it.

https://github.com/PyTorchLightning/pytorch-lightning/blob/master/pytorch_lightning/trainer/optimizers.py#L44:L47

@rohitgr7
Copy link
Contributor

True. not a valid configuration. Can you add a condition here: https://github.com/PyTorchLightning/pytorch-lightning/blob/204a0a2d03ce7dfb014e347f1d34a49ef5e86902/pytorch_lightning/trainer/optimizers.py#L44

@Borda Borda added feature Is an improvement or enhancement tuner labels Nov 30, 2020
@Borda Borda added this to the 1.1.x milestone Nov 30, 2020
… used.

In the case when optimizer frequencies are specified,
the LR scheduler corresponding to a particular optimizer is updated
only when that optimizer is being used in the training loop or epoch.
@awaelchli awaelchli force-pushed the bug/lr_scheds_update branch from 28f1cdf to a46cbca Compare March 9, 2021 09:32
@mergify mergify bot removed the has conflicts label Mar 9, 2021
""" Verify that learning rate scheduling is working """

hparams = EvalModelTemplate.get_default_hparams()
model = EvalModelTemplate(**hparams)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you replace this with BoringModel?

@Borda Borda modified the milestones: 1.2.x, 1.3 Apr 18, 2021
@edenlightning
Copy link
Contributor

@carmocca mind help getting this merged?

@carmocca carmocca self-assigned this May 3, 2021
@hemildesai hemildesai requested a review from kaushikb11 as a code owner May 4, 2021 00:11
@mergify mergify bot removed the has conflicts label May 4, 2021
@carmocca carmocca dismissed tchaton’s stale review May 4, 2021 00:49

Request no longer applies

@carmocca carmocca added ready PRs ready to be merged and removed tuner labels May 4, 2021
Comment on lines 53 to 55
hparams = EvalModelTemplate.get_default_hparams()
model = EvalModelTemplate(**hparams)
model.configure_optimizers = model.configure_optimizers__multiple_schedulers
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there an issue for converting all of the old test utilities to boring model / boring datamodule equivalents? Maybe something we can guarantee for v1.4 to simplify testing?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have an issue for it. Just doing it little by little and making sure all new code uses BoringModel

Maybe something we can guarantee for v1.4 to simplify testing?

The benefit is a considerable speedup, more than simplification

Copy link
Contributor

@awaelchli awaelchli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm
thanks for the fix.
the pr could have avoided the refactors in the tests. IMO should have been done in a separate pr for a more careful review.

@tchaton tchaton merged commit 82c19e1 into Lightning-AI:master May 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working ready PRs ready to be merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Learning Rate schedulers do not follow the optimizer frequencies.
10 participants