-
Notifications
You must be signed in to change notification settings - Fork 36
InitContext, part 3 - Introduce InitContext
#981
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
Conversation
Benchmark Report for Commit 6705d7bComputer InformationBenchmark Results |
|
DynamicPPL.jl documentation for PR #981 is available at: |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## breaking #981 +/- ##
============================================
+ Coverage 82.26% 82.53% +0.26%
============================================
Files 38 39 +1
Lines 3947 4008 +61
============================================
+ Hits 3247 3308 +61
Misses 700 700 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| """ | ||
| prefix(model::Model, x::VarName) | ||
| prefix(model::Model, x::Val{sym}) | ||
| prefix(model::Model, x::Any) | ||
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 code was shifted verbatim to src/model.jl to avoid circular dependencies between files.
90e95e1 to
21cf568
Compare
InitContextInitContext, part 3 - Introduce InitContext
025aa8b to
b55c1e1
Compare
5f60c46 to
4408efb
Compare
4408efb to
9c07727
Compare
9c07727 to
ef038c6
Compare
ef038c6 to
5961ca9
Compare
5961ca9 to
0656487
Compare
fd78d42 to
bfcdbb9
Compare
Note that, apart from being simpler code, Distributions.Uniform also doesn't allow the lower and upper bounds to be exactly equal (but we might like to keep that option open in DynamicPPL, e.g. if the user wants to initialise all values to the same value in linked space).
This should have been changed in #940, but slipped through as the file wasn't listed as one of the changed files.
bfcdbb9 to
ab3e8da
Compare
src/contexts/init.jl
Outdated
| !!! warning "Values must be unlinked" | ||
| The values returned by `init` are always in the untransformed space, i.e., | ||
| they must be within the support of the original distribution. That means that, | ||
| for example, `init(rng, dist, u::UniformInit)` will in general return values that |
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.
What about calling it UniformLinkedInit to avoid a confusion here?
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.
Hmmmm I don't have a super strong preference (the current docstring clarifies it, and the lack of a docstring was IMO the main problem with SampleFromUniform), but let's go with the more explicit and clearer name.
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.
Although I also don't want to give the impression that init(..., ::UniformLinkedInit) returns values in linked space. :/ On this basis I might prefer the original UniformInit a bit better.
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.
Hmm, fair point. I'm a bit torn between those two arguments, can leave as is if that's your preference.
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'll keep it as UniformInit for this PR but also check if others have an opinion, if necessary we can change in another PR before release.
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.
Renamed to InitFromUniform, it's a bit longer but I agree with @yebai that it's clearer.
| AbstractInitStrategy | ||
| Abstract type representing the possible ways of initialising new values for | ||
| the random variables in a model (e.g., when creating a new VarInfo). |
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.
Could this have a list of functions subtypes must implement methods for?
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.
Good call, done.
src/contexts/init.jl
Outdated
| return if hasvalue(p.params, vn, dist) | ||
| x = getvalue(p.params, vn, dist) | ||
| if x === missing | ||
| init(rng, vn, dist, p.default) |
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.
Could there be demand for p.default=nothing in which case this would error? I wonder if in some cases the current implementation could cause silent unexpected behaviour, e.g. if you misspell the varname and thus end up getting samples from the prior rather than the expected value.
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.
Yup. I can't remember what prompted it now, but I did think about this a while back. I don't think that this would get used anywhere in DynamicPPL, but I'm not opposed to adding it in anyway.
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.
Also, do you prefer p.default, or p.fallback?
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.
Quite ambivalent between those too. I think the docs may have used one term and the code another.
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'm starting to like fallback more, because 'the default for default' feels weird, so if you're not opinionated I'll change it.
Co-authored-by: Markus Hauru <markus@mhauru.org>
* Bump minor version * bump benchmarks compat * add a skeletal changelog * `InitContext`, part 3 - Introduce `InitContext` (#981) * Implement InitContext * Fix loading order of modules; move `prefix(::Model)` to model.jl * Add tests for InitContext behaviour * inline `rand(::Distributions.Uniform)` Note that, apart from being simpler code, Distributions.Uniform also doesn't allow the lower and upper bounds to be exactly equal (but we might like to keep that option open in DynamicPPL, e.g. if the user wants to initialise all values to the same value in linked space). * Document * Add a test to check that `init!!` doesn't change linking * Fix `push!` for VarNamedVector This should have been changed in #940, but slipped through as the file wasn't listed as one of the changed files. * Add some line breaks Co-authored-by: Markus Hauru <markus@mhauru.org> * Add the option of no fallback for ParamsInit * Improve docstrings * typo * `p.default` -> `p.fallback` * Rename `{Prior,Uniform,Params}Init` -> `InitFrom{Prior,Uniform,Params}` --------- Co-authored-by: Markus Hauru <markus@mhauru.org> * use `varname_leaves` from AbstractPPL instead (#1030) * use `varname_leaves` from AbstractPPL instead * add changelog entry * fix import * tidy occurrences of varname_leaves as well (#1031) * `InitContext`, part 4 - Use `init!!` to replace `evaluate_and_sample!!`, `predict`, `returned`, and `initialize_values` (#984) * Replace `evaluate_and_sample!!` -> `init!!` * Use `ParamsInit` for `predict`; remove `setval_and_resample!` and friends * Use `init!!` for initialisation * Paper over the `Sampling->Init` context stack (pending removal of SamplingContext) * Remove SamplingContext from JETExt to avoid triggering `Sampling->Init` pathway * Remove `predict` on vector of VarInfo * Fix some tests * Remove duplicated test * Simplify context testing * Rename FooInit -> InitFromFoo * Fix JETExt * Fix JETExt properly * Fix tests * Improve comments * Remove duplicated tests * Docstring improvements Co-authored-by: Markus Hauru <markus@mhauru.org> * Concretise `chain_sample_to_varname_dict` using chain value type * Clarify testset name * Re-add comment that shouldn't have vanished * Fix stale Requires dep * Fix default_varinfo/initialisation for odd models * Add comment to src/sampler.jl Co-authored-by: Markus Hauru <markus@mhauru.org> --------- Co-authored-by: Markus Hauru <markus@mhauru.org> * `InitContext`, part 5 - Remove `SamplingContext`, `SampleFrom{Prior,Uniform}`, `{tilde_,}assume` (#985) * Remove `SamplingContext` for good * Remove `tilde_assume` as well * Split up tilde_observe!! for Distribution / Submodel * Tidy up tilde-pipeline methods and docstrings * Fix tests * fix ambiguity * Add changelog * Update HISTORY.md Co-authored-by: Markus Hauru <markus@mhauru.org> --------- Co-authored-by: Markus Hauru <markus@mhauru.org> * fix missing import * Shuffle context code around and remove dead code (#1050) * Delete the `"del"` flag (#1058) * Delete del * Fix a typo * Add HISTORY entry about del * Fixes for Turing 0.41 (#1057) * setleafcontext(model, ctx) and various other fixes * fix a bug * Add warning for `initial_parameters=...` * Remove `resume_from` and `default_chain_type` (#1061) * Remove resume_from * Format * Fix test * remove initial_params warning * Allow more flexible `initial_params` (#1064) * Enable NamedTuple/Dict initialisation * Add more tests * fix include_all kwarg for predict, improve perf (#1068) * Fix `include_all` for predict * Fix include_all for predict, some perf improvements * Replace `Metadata.flags` with `Metadata.trans` (#1060) * Replace Medata.flags with Metadata.trans * Fix a bug * Fix a typo * Fix two bugs * Rename trans to is_transformed * Rename islinked to is_transformed, remove duplication * Change pointwise_logdensities default key type to VarName (#1071) * Change pointwise_logdensities default key type to VarName * Fix a doctest * Fix DynamicPPL / MCMCChains methods (#1076) * Reimplement pointwise_logdensities (almost completely) * Move logjoint, logprior, ... as well * Fix imports, etc * Remove tests that are failing (yes I learnt this from Claude) * Changelog * logpdf * fix docstrings * allow dict output * changelog * fix some comments * fix tests * Fix more imports * Remove stray n Co-authored-by: Markus Hauru <markus@mhauru.org> * Expand `logprior`, `loglikelihood`, and `logjoint` docstrings --------- Co-authored-by: Markus Hauru <markus@mhauru.org> * Remove `Sampler` and its interface (#1037) * Remove `Sampler` and `initialstep` * Actually just remove the entire file * forgot one function * Move sampling test utils to Turing as well * Update changelog to correctly reflect changes * [skip ci] Make changelog headings more consistent --------- Co-authored-by: Markus Hauru <markus@mhauru.org>
Part 1: Adding
hasvalueandgetvalueto AbstractPPLPart 2: Removing
hasvalueandgetvaluefrom DynamicPPLThis is Part 3/N of splitting up #967.
This PR solely adds the code for a new leaf context,
InitContext. Its behaviour is to always override existing values inside a VarInfo.A long-held goal of mine is to split up
contexts.jlandcontext_implementations.jlsuch that each context is in its own file. To this end, I've put all theInitContext-related code insidesrc/contexts/init.jl. This should, hopefully, also make reviewing easier.InitContextcomes in three forms:PriorInit: Samples values from the prior;UniformInit(min, max): Samples values from betweenminandmaxbefore invlinking them back into the support of the original distribution;ParamsInit(params): Takes values fromparams, which can be a NamedTuple or a Dict. Also takes a fallback strategy, which is used in case the varname is not found inparams.PriorInitandUniformInithave almost one-to-one correspondence withSampleFromPriorandSampleFromUniform. I haven't removed them yet because a LOT of stuff depends onSampleFromPrior. We will eventually remove all of it but doing it in a single PR would make it way too big.However,
ParamsInitis new. Its purpose is to set fixed values in a VarInfo in a principled manner. Right now, there is a fair amount of code that does low-level VarInfo manipulation by reaching inside and modifying the underlying arrays, such asinitialise_values!!, andsetval_and_resample!. This is prone to bugs, and also leads to (for example) the VarInfo's logp being out of sync. (All of that code will be removed in subsequent PRs.)ParamsInitaccomplishes the same in a much cleaner way, although in some cases (specifically, when setting initial values for sampling) it may necessitate one extra model evaluation. Because initialisation is not meant to happen within a tight loop (by definition it happens once), I don't consider performance to be an important issue.One might ask what's the difference between
InitContext{ParamsInit},ConditionContext, andFixedContext. Consider the model@model f() = x ~ Normal(). Evaluating this with each of the contexts gives the following behaviour:x ~ Normal()xin VarInfoIn other words, InitContext behaves as if you had run the model and sampled a new value for
x, but that value just so happened to be the one that you provided. In contrast, Condition and FixedContext fundamentally change the model that is being run in thatxis no longer a parameter.Closes #375.