-
Notifications
You must be signed in to change notification settings - Fork 5
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
Random Draws For SEIR Parameters Per Slot #429
base: dev
Are you sure you want to change the base?
Conversation
Created a test that shows the issue of the SEIR parameters not being randomly drawn per a slot wheras the outcome parameters are. Test currently fails.
Added a method to reinit distribution parameters. When the `Parameters` class is initialized it creates this distribution parameters but also captures the random seed at the time of initialization which makes the draws non-random across processes. Added a method to reinitialize distribution parameters when reseeding. Not a perfect solution, the ambigious random seed settings is rather confusing for development.
Added a unit test to the `Parameters` class unit tests for the `reinitialize_distributions` method that demonstrates how this method affects the seeding behavior across workers.
I did some testing of how random draws of parameters work for each parameter type, using the config config_sample_2pop_modifiers_test_random.yml which is now in the tutorials folder In the original code in the main branch, the behavior is:
Thus variation in In this branch, the behavior is:
So now variation in However note that users are likely surprised by the variation by location in If I instead run a config where for both seir and outcome modifiers I use
which is what we expect. I don't know how to make To summarize, yes this PR seems to fix the main underlying problem, but this issue has led me to notice a behavior that needs to be documented better and discussed - during forward-only simulations, when Thoughts from @jcblemai, @shauntruelove, @saraloo on the desired behavior here would be helpful. |
_test_random has one parameter of each type (seir, outcome, seir_modifiers, outcome_modifiers) that varies by slot _test_random_subpop_groups is same as above but for snpi and hnpi parameters it uses subpop_groups to force the same for all locations
Nice investigation. Agree we need to clearly document what matches / doesn't when stochastically simulating. Where in the gitbook do you think it's best to capture that? Regarding behavior, all the stochastic features should match in the same way in my opinion. Weird that spar seems to deviate, so we should figure out why that is. I kind of think that location shouldn't cause a different sample either, but it's most important that we have consistent behavior. |
I agree Alison on consistency. The current state is not motivated by anything but historical hastly made decisions during COVID (fixed R0 across subpops, but age structure different in each state). We should change that carefully. Now:
|
1f77156
to
64b180c
Compare
Hmm yes thanks for this investigation @alsnhll , agree with @jcblemai it's just historical decision making responsible for these inconsistencies. I'm not entirely sure what we should define here... I see a few arguments either way
Could use some discussion wrt how to harmonise these definitions. In any case, needs to be made clear in docs etc.
Similar inconsistencies in the npi parameters too as alison points out - ie we can group |
@@ -91,6 +91,8 @@ def onerun_delayframe_outcomes( | |||
load_ID: bool = False, | |||
sim_id2load: int = None, | |||
): | |||
np.random.seed(seed=sim_id2write) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might fix a seed in a way that is not always desirable: with classical inference, every ith iteration will have the same seed across slots. I would rely on /dev/random for now to be sure things are working correctly and keep the reproducibility of runs as a follow-up issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that suggests a fix is needed in how classical inference works - any inference method should be managing set seeding in a sensible way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fully agree. I would suggest a plan as follows:
- Make thing works correctly as people expect them (so doing the real random thing that the emcee is doing also here)
- Streamline the pathway to call gempyor (Descriptions of processes inside gempyor #463 (comment) shows 3 ways gempyor is called, but we should have one)
- Build something with seed so that the run with the above pathway is reproducible.
If we do 3. before 2. there might be places that have unexpected behavior which is IMO more critical than being reproducible (even though that's also very important)
2185416
to
89a9f0b
Compare
* Added unit test varying mp start method for `seir.run_parallel_SEIR` and `outcomes.run_parallel_outcomes`. * Unit test of `Parameters.reinitialize_parameters` now uses an explicit `ProcessPoolExecutor` to test behavior under spawn. * Added explicit seeding to `seir.onerun_SEIR` and `outcomes.onerun_delayframe_outcomes` to resolve random issues under fork.
89a9f0b
to
baed3a7
Compare
I apologize for the confusion @pearsonca and @jcblemai, but this PR has not been ready for code review but now is. I was working through the GH action failure on c828f1e, which was challenging to debug due to differences in behavior between Mac+Windows vs Linux. The quick version is both Reinitializing the parameters distributions was sufficient for addressing the original issue under
There is some duplicated code across these tests that I know I need to consolidate/clean up, but beyond that this is now ready for review. I will also note that I think this PR is a temporary fix to this problem, the correct longer term solution would be to explicitly manage the generator that
I'm taking this (and other commentary) to mean that we need similar tests for
Please feel free to correct me if I'm misunderstanding or if I've not got this table setup correctly (i.e. should be determined by some other variable or something). |
Impressive, and agree for the Generator thing. In the meantime though, I would advise random seed from OS random source or something else instead of fixing seed on sim_id which has blind spots as sim_id is used differently in inference and local run. not that important though.
This key can be a list of list of subpop, which are then grouped together. e.g [["California", "Utah"], ["North Carolina", South Carolina"]] means that "California", "Utah" will have one value, and "North Carolina", South Carolina" another, and the rest of the subpopulation will have independent values. This is a key for modifiers |
Work on this has been paused until after the next release due to higher priority items. |
Describe your changes.
This pull request addresses the bug described in GH-406 where new seir parameters were not drawn across slots.
Does this pull request make any user interface changes? If so please describe.
The user interface changes are:
Parameters.reinitialize_distributions
method that recreates the randomly drawn seir parameters so that they do not hold onto the prior random state, andSEIR.run_parallel_SEIR
will now draw random seir parameters across jobs.These changes have not been documented yet, @alsnhll where do you think is the best place to describe this behavior (I'll make these changes before marking this PR as ready for review)?
What does your pull request address? Tag relevant issues.
This pull request addresses GH-406.
Tag relevant team members.
@alsnhll