-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
LaTeX and str representations for v4 #4692
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
This value was not representative of its name.
…d basic dists These changes can be summarized as follows: - `Model` objects now track fully functional Theano graphs that represent all relationships between random and "deterministic" variables. These graphs are called these "sample-space" graphs. `Model.unobserved_RVs`, `Model.basic_RVs`, `Model.free_RVs`, and `Model.observed_RVs` contain these graphs (i.e. `TensorVariable`s), which are generated by `RandomVariable` `Op`s. - For each random variable, there is now a corresponding "measure-space" variable (i.e. a `TensorVariable` that corresponds to said variable in a log-likelihood graph). These variables are available as `rv_var.tag.value_var`, for each random variable `rv_var`, or via `Model.vars`. - Log-likelihood (i.e. measure-space) graphs are now created for individual random variables by way of the generic functions `logpt`, `logcdf`, `logp_nojac`, and `logpt_sum` in `pymc3.distributions`. - Numerous uses of concrete shape information stemming from `Model` objects (e.g. `Model.size`) have been removed/refactored. - Use of `FreeRV`, `ObservedRV`, `MultiObservedRV`, and `TransformedRV` has been deprecated. The information previously stored in these classes is now tracked using `TensorVariable.tag`, and log-likelihoods are generated using the aforementioned `log*` generic functions.
This commit changes `DictToArrayBijection` so that it returns a `RaveledVars` datatype that contains the original raveled and concatenated vector along with the information needed to revert it back to dictionay/variables form. Simply put, the variables-to-single-vector mapping steps have been pushed away from the model object and its symbolic terms and closer to the (sampling) processes that produce and work with `ndarray` values for said terms. In doing so, we can operate under fewer unnecessarily strong assumptions (e.g. that the shapes of each term are static and equal to the initial test points), and let the sampling processes that require vector-only steps deal with any changes in the mappings.
The approach currently being used is rather inefficient. Instead, we should change the `size` parameters for `RandomVariable` terms in the sample-space graph(s) so that they match arrays of the inputs in the trace and the desired number of output samples. This would allow the compiled graph to vectorize operations (when it can) and sample variables more efficiently in large batches.
Classes and functions removed: - PyMC3Variable - ObservedRV - FreeRV - MultiObservedRV - TransformedRV - ArrayOrdering - VarMap - DataMap - _DrawValuesContext - _DrawValuesContextBlocker - is_fast_drawable - _compile_theano_function - vectorize_theano_function - get_vectorize_signature - _draw_value - draw_values - generate_samples - fast_sample_posterior_predictive Modules removed: - pymc3.distributions.posterior_predictive - pymc3.tests.test_random
* refactor Skewnormal and Rice distribution * add test for rice b and skewnorm tau params * change default parameter to b * Add float32 xfail to `test_rice` Co-authored-by: Farhan Reynaldo <[email protected]> Co-authored-by: Ricardo <[email protected]>
I agree with @Spaak that this code seems a bit leaner for what we're trying to accomplish here. And if I understand correctly the linked code is not part of Aesara. @brandonwillard or is there existing functionality you are referring to we can leverage here? I really like the refactoring into a separate file as well as the new output which looks much better. |
Seems like this needs to be rebased. Curious if the Edit: Parameter names would indeed be nice to have |
I just rebased, curious to see what will happen with the tests indeed.
Yep, I agree. I think that if all ✔️ this could be merged and I'll work on adding the parameter names after that. I may have to touch some Aesara code for that, too. |
Co-authored-by: Thomas Wiecki <[email protected]>
Yes, that's why I provided a link to it in that comment.
The code in To clarify, Now, within You can see some of those features in this old example, where their More importantly, the Also, what happens when this dynamic class change is applied to something that's already a subclass of These concerns—along with a few others (e.g. lack of extensibility, costly graph walking within the built-in |
By the way, by "...get everything we want/need without adding much/any code to PyMC3..." I mean that we can add the generic LaTeX printing features from |
@brandonwillard How do you mean "invasively changing a class type"? Are you referring to https://github.com/pymc-devs/pymc3/pull/4692/files#diff-2cba9a36ecb19a6894133cbc03512d4e0dd70c9f681250bf45dcd72f75a56a3dR165? If this introduces unwanted side-effects we should talk about them. However, I think this PR will make future refactorings (once aesara has that functionality) much simpler because now everything is contained in one place. So in the interest of moving us forward I think we should merge. |
This PR uses the same Aesara
My point about this PR being leaner was specifically that it does not provide support for entire computational graphs, but only a quick overview of PyMC3 variables and probabilistic models (I wasn't making a point about number of lines of code).
Ah, that clarifies things, you meant to add the code from symbolic-pymc to Aesara, rather than to PyMC3 (thereby leading to less code needed in PyMC3). Once the support is there in Aesara, we can always drop the functionality in this PR. Especially now that it's refactored into one module that should be easy to do, as @twiecki points out.
Yes, that's what's being referred to, and this is worth more discussion. I agree that this may have side effects that are so far not showing up. The (only) reason that I used this dynamic type patching is that Python's builtin
otherwise the user would have to type In v3, I used the same technique but only for I agree that this type patching is not the cleanest solution. (And actually Python's refusal to use patched
(plus analogous change for If we want to go head with the general (simple) functionality in this PR (for now), but with the dynamic type patching taken out, |
Is that a path that you think you can help with? Just from looking at the code so far. Wondering how much work that would be and if we should just get it right from the beginning. Alternatively, the current solution with pymc-devs/pytensor#417 sounds like it would reduce the risk of side-effects and improve the status quo so I'm comfortable with that path too. |
@Spaak I changed the base to main so we can delete the I'm not sure what the state of LaTeX representations and also |
I'm closing this PR (rebasing too much headache) and will file a new one in a few days. I intend to take the following approach:
|
@Spaak Sounds great. CC @brandonwillard about this approach. |
This PR adds LaTeX and string representations for distributions and
Model
s for v4, fixing #4494. Specifically, it adds the following functionality:after which (in interactive console session), we can do:
Additionally, in Jupyter notebooks, the model now renders as LaTeX (MathJax, to be precise):
There are some changes w.r.t. how this functionality was implemented in v3:
RandomVariable._print_name
.N(0, 1)
instead ofN(mu=0, sigma=1)
. This is a consequence ofRandomVariable
's interface. I considered using inspection to extract the parameter names (like before). However, Aesara follows numpy's naming (e.g. "loc" and "scale" forNormalRV
), while PyMC3 uses its own ("mu" and "sigma"). For now I decided not to include parameter names to avoid this mismatch, but am open to implement it after all. In general I would actually prefer to have the parameter names.f(f(f(f(f(a)), f(f(f(b))), ...
. I've now changed this such that the entire graph going into a parameter is flattened, and onlyf(a1, a2, ..., aN)
is left, for everyRandomVariable
a
occurring in the graph. This should make the strings a lot easier to read.printing
.I've not yet updated the tests (I think all str/latex-related ones are all failing now on v4); once we agree this is a good way forward I will.