You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: usage/tracking-extra-quantities/index.qmd
+70-16Lines changed: 70 additions & 16 deletions
Original file line number
Diff line number
Diff line change
@@ -13,11 +13,14 @@ using Pkg;
13
13
Pkg.instantiate();
14
14
```
15
15
16
-
Often, the most natural parameterization for a model is not the most computationally feasible.
16
+
Often, there are quantities in models that we might be interested in viewing the values of, but which are not random variables in the model that are explicitly drawn from a distribution.
17
+
18
+
As a motivating example, the most natural parameterization for a model might not the most computationally feasible.
17
19
Consider the following (efficiently reparametrized) implementation of Neal's funnel [(Neal, 2003)](https://arxiv.org/abs/physics/0009028):
18
20
19
21
```{julia}
20
22
using Turing
23
+
setprogress!(false)
21
24
22
25
@model function Neal()
23
26
# Raw draws
@@ -33,9 +36,7 @@ end
33
36
34
37
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
38
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
+
There are two ways to track these extra quantities in Turing.jl.
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.
79
+
The sampled chain does not contain `x` and `y`, but we can extract the values using the `returned` function.
80
+
Calling this function outputs an array:
80
81
81
82
```{julia}
82
-
returned(Neal_return(), chain)
83
+
nts = returned(Neal_return(), chain)
83
84
```
84
85
85
-
Each element of this corresponds to an array with the values of `x1, x2, ..., x9, y` for each posterior sample.
86
+
where each element of which is a NamedTuple, as specified in the return statement of the model.
87
+
88
+
```{julia}
89
+
nts[1]
90
+
```
91
+
92
+
## Which to use?
93
+
94
+
There are some pros and cons of using `returned`, as opposed to `:=`.
95
+
96
+
Firstly, `returned` is more flexible, as it allows you to track any type of object; `:=` only works with variables that can be inserted into an `MCMCChains.Chains` object.
97
+
(Notice that `x` is a vector, and in the first case where we used `:=`, reconstructing the vector value of `x` can also be rather annoying as the chain stores each individual element of `x` separately.)
98
+
99
+
However, if used carelessly, `returned` can lead to unnecessary computation.
100
+
For example, in `Neal_return()` above, the `x` and `y` variables are also calculated during the inference process (i.e. the call to `sample()`), but are then thrown away.
101
+
They are then calculated _again_ when `returned()` is called.
102
+
103
+
To avoid this, you will essentially have to create two different models, one for inference and one for post-inference.
104
+
The simplest way of doing this is to add a parameter to the model argument:
105
+
106
+
```{julia}
107
+
@model function Neal_coloneq_optional(track::Bool)
108
+
# Raw draws
109
+
y_raw ~ Normal(0, 1)
110
+
x_raw ~ arraydist([Normal(0, 1) for i in 1:9])
111
+
112
+
if track
113
+
y = 3 * y_raw
114
+
x = exp.(y ./ 2) .* x_raw
115
+
return (x=x, y=y)
116
+
else
117
+
return nothing
118
+
end
119
+
end
86
120
87
-
In this case, it might be useful to reorganize our output into a matrix for plotting:
0 commit comments