Skip to content

Commit 9d17281

Browse files
committed
Update generated_quantities -> returned; add some docs on :=
1 parent 584f1d5 commit 9d17281

File tree

6 files changed

+103
-73
lines changed

6 files changed

+103
-73
lines changed

_quarto.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ website:
6060
- usage/custom-distribution/index.qmd
6161
- usage/probability-interface/index.qmd
6262
- usage/modifying-logprob/index.qmd
63-
- usage/generated-quantities/index.qmd
63+
- usage/tracking-extra-quantities/index.qmd
6464
- usage/mode-estimation/index.qmd
6565
- usage/performance-tips/index.qmd
6666
- usage/sampler-visualisation/index.qmd
@@ -190,7 +190,7 @@ using-turing-external-samplers: tutorials/docs-16-using-turing-external-samplers
190190
using-turing-mode-estimation: tutorials/docs-17-mode-estimation
191191
usage-probability-interface: tutorials/usage-probability-interface
192192
usage-custom-distribution: tutorials/usage-custom-distribution
193-
usage-generated-quantities: tutorials/usage-generated-quantities
193+
usage-tracking-extra-quantities: tutorials/tracking-extra-quantities
194194
usage-modifying-logprob: tutorials/usage-modifying-logprob
195195

196196
contributing-guide: developers/contributing

tutorials/bayesian-time-series-analysis/index.qmd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ end
175175
176176
function get_decomposition(model, x, cyclic_features, chain, op)
177177
chain_params = Turing.MCMCChains.get_sections(chain, :parameters)
178-
return generated_quantities(model(x, cyclic_features, op), chain_params)
178+
return returned(model(x, cyclic_features, op), chain_params)
179179
end
180180
181181
function plot_fit(x, y, decomp, ymax)

tutorials/gaussian-mixture-models/index.qmd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ chains = sample(model, sampler, MCMCThreads(), nsamples, nchains, discard_initia
403403
Given a sample from the marginalized posterior, these assignments can be recovered with:
404404

405405
```{julia}
406-
assignments = mean(generated_quantities(gmm_recover(x), chains));
406+
assignments = mean(returned(gmm_recover(x), chains));
407407
```
408408

409409
```{julia}

tutorials/gaussian-processes-introduction/index.qmd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ posterior probability of success at any distance we choose:
146146

147147
```{julia}
148148
d_pred = 1:0.2:21
149-
samples = map(generated_quantities(m_post, chn)[1:10:end]) do x
149+
samples = map(returned(m_post, chn)[1:10:end]) do x
150150
return logistic.(rand(posterior(x.fx, x.f_latent)(d_pred, 1e-4)))
151151
end
152152
p = plot()

usage/generated-quantities/index.qmd

Lines changed: 0 additions & 68 deletions
This file was deleted.
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
---
2+
title: Tracking Extra Quantities
3+
engine: julia
4+
aliases:
5+
- ../../tutorials/usage-generated-quantities/index.html
6+
- ../generated-quantities/index.html
7+
---
8+
9+
```{julia}
10+
#| echo: false
11+
#| output: false
12+
using Pkg;
13+
Pkg.instantiate();
14+
```
15+
16+
Often, the most natural parameterization for a model is not the most computationally feasible.
17+
Consider the following (efficiently reparametrized) implementation of Neal's funnel [(Neal, 2003)](https://arxiv.org/abs/physics/0009028):
18+
19+
```{julia}
20+
using Turing
21+
22+
@model function Neal()
23+
# Raw draws
24+
y_raw ~ Normal(0, 1)
25+
x_raw ~ arraydist([Normal(0, 1) for i in 1:9])
26+
27+
# Transform:
28+
y = 3 * y_raw
29+
x = exp.(y ./ 2) .* x_raw
30+
return nothing
31+
end
32+
```
33+
34+
In this case, the random variables exposed in the chain (`x_raw`, `y_raw`) are not in a helpful form — what we're after are the deterministically transformed variables `x` and `y`.
35+
36+
More generally, there are often quantities in our models that we might be interested in viewing, but which are not explicitly present in our chain.
37+
38+
There are two ways of tracking such extra quantities.
39+
40+
## Using `:=` (during inference)
41+
42+
The first way is to use the `:=` operator, which behaves exactly like `=` except that the values of the variables on its left-hand side are automatically added to the chain returned by the sampler.
43+
For example:
44+
45+
```{julia}
46+
@model function Neal_coloneq()
47+
# Raw draws
48+
y_raw ~ Normal(0, 1)
49+
x_raw ~ arraydist([Normal(0, 1) for i in 1:9])
50+
51+
# Transform:
52+
y := 3 * y_raw
53+
x := exp.(y ./ 2) .* x_raw
54+
end
55+
56+
sample(Neal_coloneq(), NUTS(), 1000; progress=false)
57+
```
58+
59+
## Using `returned` (post-inference)
60+
61+
Alternatively, one can specify the extra quantities as part of the model function's return statement:
62+
63+
```{julia}
64+
@model function Neal_return()
65+
# Raw draws
66+
y_raw ~ Normal(0, 1)
67+
x_raw ~ arraydist([Normal(0, 1) for i in 1:9])
68+
69+
# Transform and return as a NamedTuple
70+
y = 3 * y_raw
71+
x = exp.(y ./ 2) .* x_raw
72+
return [x; y]
73+
end
74+
75+
chain = sample(Neal_return(), NUTS(), 1000; progress=false)
76+
```
77+
78+
This chain does not contain `x` and `y`, but we can extract the values using the `returned` function.
79+
Calling this function outputs an array of values specified in the return statement of the model.
80+
81+
```{julia}
82+
returned(Neal_return(), chain)
83+
```
84+
85+
Each element of this corresponds to an array with the values of `x1, x2, ..., x9, y` for each posterior sample.
86+
87+
In this case, it might be useful to reorganize our output into a matrix for plotting:
88+
89+
```{julia}
90+
reparam_chain = reduce(hcat, returned(Neal_return(), chain))'
91+
```
92+
93+
from which we can recover a vector of our samples:
94+
95+
```{julia}
96+
x1_samples = reparam_chain[:, 1]
97+
y_samples = reparam_chain[:, 10]
98+
```

0 commit comments

Comments
 (0)