[Feature Request] 1) More details in `render_model` (esp. for `pyro.params`); 2) Returning dictionary from render_mode
See original GitHub issueHi, From the MLE-MAP tutorial, we have the following models
MLE model
def model_mle(data):
f = pyro.param("latent_fairness", torch.tensor(0.5),
constraint=constraints.unit_interval)
with pyro.plate("data", data.size(0)):
pyro.sample("obs", dist.Bernoulli(f), obs=data)
If we render this, we get something like the following image
MAP model
def original_model(data):
f = pyro.sample("latent_fairness", dist.Beta(10.0, 10.0))
with pyro.plate("data", data.size(0)):
pyro.sample("obs", dist.Bernoulli(f), obs=data)
If we render this, we get something like the following image

Coin toss graphical model images from the popular Maths for ML book
This is from Figure 8.10

We’d expect our MLE model render to look like 8.10 b) and our MAP model to look like 8.10 c)
So, when we have latent_fairness
as a parameter, it should perhaps just be written as latent_fairness
and under the MAP model, it should be parameterised by the Beta
distribution.
From the pyro render of the MLE model, it is not easily visible how observations are related to latent_fairness
.
Feature Requests
So, I have two questions/requests
- Would it make sense to have
pyro.params
also show in renders. The difference in the renders betweenpyro.sample
andpyro.parameter
would be the associated distribution (and thus hyperparams) inpyro.sample
- Would it be possible to allow render to additionally return a dictionary when calling
render_model
? For example, once can then use that dictionary to create their own graphical models, for example using tikz-bayesnet. For example, the code below reproduces the Figure 8.10 from MML book shown above.3.
Click to toggle contents of `code`
\documentclass[a4paper]{article}
\usepackage{caption}
\usepackage{subcaption}
\usepackage{tikz}
\usetikzlibrary{bayesnet}
\usepackage{booktabs}
\setlength{\tabcolsep}{12pt}
\begin{document}
\begin{figure}[ht]
\begin{center}
\begin{tabular}{@{}cccc@{}}
\toprule
$x_N$ explicit & Plate Notation & Hyperparameters on $\mu$ & Factor\\ \midrule
& & & \\
\begin{tikzpicture}
\node[obs] (x1) {$x_1$};
\node[const, right=0.5cm of x1] (dots) {$\cdots$};
\node[obs, right=0.5cm of dots] (xn) {$x_N$};
\node[latent, above=of dots] (mu) {$\mathbf{\mu}$};
\edge {mu} {x1,dots,xn} ; %
\end{tikzpicture}&
\begin{tikzpicture}
\node[obs] (xn) {$x_n$};
\node[latent, above=of xn] (mu) {$\mathbf{\mu}$};
\plate{}{(xn)}{$n = 1, \cdots, N$};
\edge {mu} {xn} ; %
\end{tikzpicture} &
\begin{tikzpicture}
\node[obs] (xn) {$x_n$};
\node[latent, above=of xn] (mu) {$\mathbf{\mu}$};
\node[const, right=0.5cm of mu] (beta) {$\mathbf{\beta}$};
\node[const, left=0.5cm of mu] (alpha) {$\mathbf{\alpha}$};
\plate{}{(xn)}{$n = 1, \cdots, N$};
\edge {mu} {xn} ; %
\edge {alpha,beta} {mu} ; %
\end{tikzpicture}
&
\begin{tikzpicture}
\node[obs] (xn) {$x_n$};
\node[latent, above=of xn] (mu) {$\mathbf{\mu}$};
\factor[above=of xn] {y-f} {left:${Ber}$} {} {} ; %
\node[const, above=1 of mu, xshift=0.5cm] (beta) {$\mathbf{\beta}$};
\node[const, above=1 of mu, xshift=-0.5cm] (alpha) {$\mathbf{\alpha}$};
\factor[above=of mu] {mu-f} {left:${Beta}$} {} {} ; %
\plate{}{(xn)}{$n = 1, \cdots, N$};
\edge {mu} {xn} ; %
\edge {alpha,beta} {mu-f} ; %
\edge {mu-f}{mu} ; %
\end{tikzpicture}
\end{tabular}
\end{center}
\caption{Graphical models for a repeated Bernoulli experiment.}
\end{figure}
\end{document}
Issue Analytics
- State:
- Created 2 years ago
- Reactions:2
- Comments:5 (5 by maintainers)
Top Results From Across the Web
Optimization - Pyro Documentation
The module pyro.optim provides support for optimization in Pyro. ... of learning arguments for the optimizer or a callable that returns such dictionaries...
Read more >augmentation_code/models.py at master - GitHub
"""Abstract class for multinomial logistic regression on augmented data. Input has size B x T x ..., where B is batch size and...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Hi @fritzo and team, My name is Karm. I am working with Prof. @nipunbatra and lab colleague @patel-zeel. I made desired changes in the code and tested it on the following examples.
MLE Model 1
{‘sample_sample’: {‘obs’: []}, ‘sample_param’: {‘obs’: [‘sd’, ‘mu’]}, ‘sample_dist’: {‘obs’: ‘Normal’}, ‘param_constraint’: {‘mu’: Interval(lower_bound=0.0, upper_bound=1.0), ‘sd’: GreaterThanEq(lower_bound=0)}, ‘plate_sample’: {‘plate_data’: [‘obs’]}, ‘observed’: [‘obs’]}
MAP Model 1
{‘sample_sample’: {‘mu’: [], ‘sd’: [‘mu’], ‘obs’: [‘sd’, ‘mu’]}, ‘sample_param’: {‘mu’: [‘k1’], ‘sd’: [‘k1’], ‘obs’: []}, ‘sample_dist’: {‘mu’: ‘Normal’, ‘sd’: ‘LogNormal’, ‘obs’: ‘Normal’}, ‘param_constraint’: {‘k1’: Real()}, ‘plate_sample’: {‘plate_data’: [‘obs’]}, ‘observed’: [‘obs’]}
MAP Model 2
{‘sample_sample’: {‘mu’: [], ‘sd’: [‘mu’], ‘obs’: [‘sd’, ‘mu’]}, ‘sample_param’: {‘mu’: [‘k1’], ‘sd’: [‘k1’], ‘obs’: []}, ‘sample_dist’: {‘mu’: ‘Normal’, ‘sd’: ‘LogNormal’, ‘obs’: ‘Normal’}, ‘param_constraint’: {‘k1’: Real()}, ‘plate_sample’: {‘plate_data’: [‘obs’]}, ‘observed’: [‘obs’]}
Changes made in code
Broadly, I made the following changes in pyro.infer.inspect.py.
sample_param
in the dictionary returned byget_model_relation()
to get a param that depends on a given sample. In methodget_model_relations()
I observed the output oftrace.nodes
, I found that there is no provenance tracking for params and I think without provenance tracking, we are not able to get dependent params. Since there is method named_pyro_post_sample()
in classTrackProvenance(Messenger)
which assigning provenance to sample. So I added a similar method for params named_pyro_post_param()
in the same class. This method is called while getting the trace,trace = poutine.trace(model).get_trace(*model_args, **model_kwargs)
.Then, to add values in
sample_param
I followed a similar procedure as followed for adding values insample_sample
.param_constraint
to store constraints of params. This result will be required by the methodgenerate_graph_specification()
.render_params: bool = False
in both methodsrender_model()
andgenerate_graph_specification()
. This argument will ensure optional output showing params in graph.generate_graph_specification()
, dictionarynode_data
looks like below for sample variable,I added an additional key
constraint
in node_data for param only, Note that following changes apply only whenrender_params = True
.Further,
edge_list
andplate_groups
will also be updated by adding params data. 5. In therender_graph()
method, I kept the shape of the param asplain
and I added a code to show the constraint of params.@fritzo, please give your feedback on this. Can I make PR If the dictionary and graph meet your expectations?
Hi @nipunbatra, regarding
render_params
argument torender_model
and possibly printing their constraints ifrender_distributions == True
. @fehiepsi might also like this feature in NumPyro.render_model()
already has a well-defined return value and thus should preserve that return value for backwards compatibility, you could instead get structural information from the internals ofrender_model()
, namely usingget_model_relations()
andgenerate_graph_specification()
: https://github.com/pyro-ppl/pyro/blob/f4fafc5c7fa0dc5a377ceb06ec59a234bf3ac465/pyro/infer/inspect.py#L494-L495 I’d recommend also checking out the other helper functions in pyro.infer.inspect, including get_dependencies().