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

Interrupt optimization through IncorporateRunResultCallback #765

Merged
merged 4 commits into from
Aug 26, 2021

Conversation

thomashlvt
Copy link
Contributor

@thomashlvt thomashlvt commented Aug 18, 2021

I wanted to implement a hook in autosklearn for the user to be able to implement his own stopping strategy. @eddiebergman suggested here to use the IncorporateRunResultCallback of SMAC. However, currently the callback cannot interrupt the optimization loop.

I now added the possibility to gracefully abort the optimization by returning False from the callback (when returning None the optimization still continues for backward compatibility). I also added a unit test to test this.

Please let me know if there is anything I should change/add/fix. I'm very happy to contribute :)

@codecov
Copy link

codecov bot commented Aug 18, 2021

Codecov Report

Merging #765 (66ca028) into development (22077ce) will increase coverage by 0.05%.
The diff coverage is 100.00%.

❗ Current head 66ca028 differs from pull request most recent head b5f8487. Consider uploading reports for the commit b5f8487 to get more accurate results
Impacted file tree graph

@@               Coverage Diff               @@
##           development     #765      +/-   ##
===============================================
+ Coverage        86.97%   87.02%   +0.05%     
===============================================
  Files               68       68              
  Lines             6218     6222       +4     
===============================================
+ Hits              5408     5415       +7     
+ Misses             810      807       -3     
Impacted Files Coverage Δ
smac/callbacks.py 80.00% <100.00%> (+2.22%) ⬆️
smac/optimizer/smbo.py 90.32% <100.00%> (+0.19%) ⬆️
smac/intensification/intensification.py 95.80% <0.00%> (+0.38%) ⬆️
smac/stats/stats.py 92.55% <0.00%> (+2.12%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 22077ce...b5f8487. Read the comment docs.

Copy link
Contributor

@eddiebergman eddiebergman left a comment

Choose a reason for hiding this comment

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

Hi @thomashlvt,

Glad you could get this done so quickly. I looked through the code and the test and it seems fairly straightforward and non-disruptive which is very nice! I have added one question in the review.

I imagine this feature will wanted to be documented somewhere but there should be someone more involved with SMAC to review this properly.

If there is no activity on this soon I will bump someone to take a look

@@ -50,7 +50,8 @@ class TestSMBO(unittest.TestCase):
def setUp(self):
self.scenario = Scenario({'cs': test_helpers.get_branin_config_space(),
'run_obj': 'quality',
'output_dir': 'data-test_smbo'})
'output_dir': 'data-test_smbo',
"runcount-limit": 5})
self.output_dirs = []
Copy link
Contributor

Choose a reason for hiding this comment

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

Was there a need to include a "runcount-limit"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If the TestCallback would not return False at some point, or if stopping the optimization loop would not work, the test would run forever. This is not the case, but I thought it'd be better to have this safety net. I'm not sure if this has an impact on the other tests. Let me know if you would like me to remove this, or constrain it to test_incorporate_run_results_callback_stop_loop.

Copy link
Contributor

Choose a reason for hiding this comment

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

This makes sense to me but hopefully someone more familiar with all the tests can decide.

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks good to me

@@ -1,4 +1,5 @@
from typing import TYPE_CHECKING
from typing import Optional

Copy link
Contributor

@eddiebergman eddiebergman Aug 18, 2021

Choose a reason for hiding this comment

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

The two instances of from typing import X can be reduced to 1

Copy link
Contributor

@mfeurer mfeurer left a comment

Choose a reason for hiding this comment

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

Looks good to me and I agree with all suggestions from @eddiebergman

@@ -50,7 +50,8 @@ class TestSMBO(unittest.TestCase):
def setUp(self):
self.scenario = Scenario({'cs': test_helpers.get_branin_config_space(),
'run_obj': 'quality',
'output_dir': 'data-test_smbo'})
'output_dir': 'data-test_smbo',
"runcount-limit": 5})
self.output_dirs = []
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks good to me

@eddiebergman
Copy link
Contributor

@renesass Would you have any suggestions on where to document this? I'd be happy to merge it functionally but I feel like this functionality will get lost and forgotten about unless it's written prominently in the docs somewhere.

My suggestion would be to make a new early_stopping.rst file under doc and add it to the toc tree of manual.rst. This way it has a dedicated header entry in the manual as something SMAC can do. I don't think a full blown example is necessary but a single paragraph with a code snippet demonstrating it would be nice.

Creating a dedicated file and manual section for it also means less barrier to modifying the docs for this in the future.

@renesass
Copy link
Collaborator

I'd suggest to add "Advanced Usage" below "Basic Usage" under the manual tree. We can add a small example in this file for the early stopping scenario too. In the future, we can always update this file instead of creating others.

@renesass renesass merged commit 91edd06 into automl:development Aug 26, 2021
github-actions bot pushed a commit that referenced this pull request Aug 26, 2021
@eddiebergman
Copy link
Contributor

Did we ever add documentation on this? Sorting out autosklearn issues and it would be good to be able to link to any documentation on this functionality?

@renesass
Copy link
Collaborator

We didn't.

@eddiebergman
Copy link
Contributor

Cool no problem, we have it as an issue, we will bug you about it when we deal with it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants