-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Remove initval from Model class and add function to draw one #4942
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
Comments
My only concern is with
Are we asking users to draw all initvals for all model variables (and remembering to transform them)? If they want to specify only one initval for a specific variable, it's not so easy to plug-it in, because it might require changes in other variable initvals in order to obtain a set of initial values that is internally consistent. The function That has nothing to do with whether initvals are defined during variable instantiation, and what gets stored where. |
I guess this is not cached anymore inside the model object right? That's fine, but we need to go through the many methods in the codebase that make use of it, and make sure it's being propagated |
The way I imagine is that we add support to our predictive sampling functions to condition on values and hook into that machinery. And instead of |
I have a major concern with this: User experience. I know I know, lately we don't care about user experience as much as we care about chastity, but if initial values can't be set at RV creation (or a line after, but that's basically the same) this creates a need to keep around this information all the way until An incredibly powerful modeling workflow is the creation of submodules of a model. Black-boxing parts of a data generating process into a function that creates a sub-graph for it makes it possible to build quite sophisticated multi-level, hybrid models. Often times it is right in these submodules where setting initial values increases the robustness of the overall modeling workflow. I don't see why we should be sacrificing this powerful workflow without any real advantages over the lazy symbolic evaluation we discussed earlier. The rezieability, choking the sampler, or having an arbitrary point associated with a model are all addressed by making |
@michaelosthege I agree that it is a downgrade in UX, but I think it is very minor. 99% of the models I've seen do not require an |
Yeah I like that idea. It's basically what I was suggesting in #4924 with the name of So then what is the difference between this and #4924:
Is that it? Or are there other differences? |
To me it makes much more sense, both for users and developers, to have initvals passed to |
@ricardoV94 That all sounds right to me. |
Nothing stops a module from implementing a more sophisticated initval creation function. If we see such logic is being replicated across the codebase (which I think we were seeing a bit with the partial updating + transformation of initvals) then we can always refactor into a more general method. Do you have any example where the proposed method would not suffice? |
@twiecki that's because in Do we really want to knowingly downgrade the UX and at the same time removing any chance to get back the old behavior without major changes to user code?
You can easily do that with the symbolic
Under the hood that needs to happen inside
@ricardoV94 this example is a submodule for creating a random walk. It is used by a user level function where users don't even need to know what PyMC3 is. Much later in their code users may decide to sample the model: t, y = my dataset
draft_result = fit_mu_t(t, y, ...) # builds the PyMC3 model and runs find_MAP
# do some plotting
# now decide to sample the posterior
with draft_result.pmodel:
# Here I don't have a handle on the initial values.
# As a user I don't even know - or care - about the variables inside
pymc3.sample() The proposal by @twiecki to drop the I don't even know what the most elegant solution would be from a user perspective. I would probably just monkey patch a |
Right, I would actually propose to revert the way the initval is drawn to how we did it in @michaelosthege for your example, I can definitely see how attaching a point to the model seems easier here. In principle, you could have your Alternatively, there could be a |
Less nice? And what's next then, should we do the same for I'm hyperbolizing, of course, but coming back to the points from your proposal what really are the advantages of ditching the API ?
Conceptually yes, but from a UX perspective it's a nightmare. And technically we don't even create initvals if we keep them symbolic and it also solves the problems with samplers/dimensionality in an elegant "v4" style.
Removing an "odd design" choice that has clear UX advantages doesn't sound like a good argument. And again, a symbolic |
Separately, I also talked to @junpenglao about initializing NUTS: For example, if you have a Cauchy prior and prior sample could be HUGE, and it either takes forever to tune or outright doesn't work So better to initialize from the U(-1, 1) in the unbounded space like Stan" So I think we should just do that. Again, I think with this method, specifying an initval manually will almost never be required, so adding symbolic |
I agree with @twiecki. What about using moments like we've done in the past? It seems to have served us well. |
@fonnesbeck ok, thanks for chiming in, I'd say we have enough votes then here to go ahead. This came up while talking to @brandonwillard so unless I misrepresented what we discussed I think he agrees too. I think moments are a good method too. From there, |
Anyone want to take this on? @ricardoV94 @kc611 @Sayam753 ? |
At the very least please please please implement the needed function to draw initial values without removing
I'm not against cleaning up the *I'm assuming we want to continue determining dependent RV's initial values conditioned on user-provided |
Why don't we start we the two features everyone seems to be on board with?
From there I agree with @michaelosthege that it's mostly a question of housekeeping. |
I like that approach.
…On Wed, Aug 18, 2021, 20:39 Ricardo Vieira ***@***.***> wrote:
Why don't we start we the two features everyone seems to be on board with?
1. RV-dispatched method to extract moments
2. A method that extracts initvals for a whole model + can have some
variables initvals set to user defined constants
From there, it's a question of housekeeping I think.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#4942 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAFETGHH4EVOA34LT5ZF6OTT5P46JANCNFSM5CJ6LE4Q>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email>
.
|
In
v3
we (ab)used the Theano.tag.test_value
to evaluate the model (Model.check_test_point
) at a set point as well as provide a starting point for the sampler, this point was stored in theModel
class. Inv4
we removed the reliance ontestvalue
and instead just have ainitial_value
dictionary inModel
that gets updated with a numpy array per RV as the RV gets created. This dict is then referenced by e.g. the sampler. If a user wants to specify their own initval for an RV, they do so during creation of the RV.After talking to @brandonwillard about several issues related to this mechanism (#4924, #4911) I propose we change this method in the following way:
initval
is not stored in theModel
object anymoreinitval
s can not be specified in RV instantiation anymore (this is rarely done in practice anyway, but sometimes it's necessary)pm.sample_prior_predictive()
(e.g.pm.sample_mean()
) to draw an initvalue.dict
mapping RV names to numpy arrays.Model.check_test_point
as well as the sampler draw aninitival
using this function when they need it.pm.sample
takes aninitval
point dict of initvals to override from the default that gets drawn. So whenpm.sample
draws an initval, it conditions the model on the override dict passed by the user. A user could also draw an initval herself, alter it, and pass that in, so that initvals for all RVs are provided in this way. The same can work forModel.check_test_point
.I think this should cover all the bases. It solves a few of the problems we've been wrestling with:
Model.initval
or the sampler will choke.Model
seems like an odd design choice and it's not clear why that should be the case.The text was updated successfully, but these errors were encountered: