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: developers/models/varinfo-overview/index.qmd
+15-11Lines changed: 15 additions & 11 deletions
Original file line number
Diff line number
Diff line change
@@ -49,7 +49,7 @@ latents = rand(Dict, model)
49
49
Simply calling `rand(model)`, by default, returns a NamedTuple.
50
50
This is fine for simple models where all variables on the left-hand side of tilde statements are standalone variables like `x`.
51
51
However, if you have indices or fields such as `x[1]` or `x.a` on the left-hand side, then the NamedTuple will not be able to represent these variables properly.
52
-
Feeding such a NamedTuple back into the model, as shown in the next section, will lead to errors.
52
+
Feeding such a NamedTuple back into the model will lead to errors.
53
53
54
54
In general, `Dict{VarName}` will always avoid such correctness issues.
55
55
:::
@@ -84,10 +84,10 @@ returned(model, latents)
84
84
85
85
The above functions are convenient, but for many 'serious' applications they might not be flexible enough.
86
86
For example, if you wanted to obtain the return value _and_ the log joint, you would have to execute the model twice: once with `returned` and once with `logjoint`.
87
-
If you want to avoid this duplicate work, you need to use a lower-level interface, which is `DynamicPPL.evaluate!!`.
88
87
88
+
If you want to avoid this duplicate work, you need to use a lower-level interface, which is `DynamicPPL.evaluate!!`.
89
89
At its core, `evaluate!!` takes a model and a VarInfo object, and returns a tuple of the return value and the new VarInfo.
90
-
So before we get to `evaluate!!`, we need to understand what a VarInfo is.
90
+
So, before we even get to `evaluate!!`, we need to understand what a VarInfo is.
91
91
92
92
A VarInfo is a container that tracks the state of model execution, as well as any outputs related to its latent variables, such as log probabilities.
93
93
DynamicPPL's source code contains many different kinds of VarInfos, each with different trade-offs.
@@ -115,7 +115,7 @@ DynamicPPL.getlogprior(v)
115
115
116
116
What about the return value?
117
117
Well, the VarInfo does not store this directly: recall that `evaluate!!` gives us back the return value separately from the updated VarInfo.
118
-
So, let's call it.
118
+
So, let's try calling it to see what happens.
119
119
The default behaviour of `evaluate!!` is to use the parameter values stored in the VarInfo during model execution.
120
120
That is, when it sees `x ~ Normal()`, it will use the value of `x` stored in `v`.
which is in line with the statement above that by default `evaluate!!` uses the values stored in the VarInfo.
135
135
136
-
At this point, the sharp reader will notice that we have not really solved the problem here.
137
-
Although the call to `DynamicPPL.evaluate!!` does indeed only execute the model once, we also had to do this once at the beginning when constructing the VarInfo.
136
+
At this point, the keen reader will notice that we have not really solved the problem here.
137
+
Although the call to `DynamicPPL.evaluate!!` does indeed only execute the model once, we also had to do this once more at the beginning when constructing the VarInfo.
138
138
139
139
Besides, we don't know how to control the parameter values used during model execution: they were simply whatever we got in the original VarInfo.
140
140
@@ -158,7 +158,7 @@ You can also provide an `AbstractRNG` as the first argument to `init!!` to contr
158
158
:::
159
159
160
160
Alternatively, to provide specific sets of values, we can use `InitFromParams(...)` to specify them.
161
-
`InitFromParams` can wrap either a `NamedTuple` or an `AbstractDict{<:VarName}`, but for reasons explained above, `Dict` is generally much preferred.
161
+
`InitFromParams` can wrap either a `NamedTuple` or an `AbstractDict{<:VarName}`, but `Dict` is generally much preferred as this guarantees correct behaviour even for complex variable names.
162
162
163
163
```{julia}
164
164
retval, v_new = DynamicPPL.init!!(
@@ -181,11 +181,15 @@ If you have a loop in which you want to repeatedly evaluate a model with differe
181
181
- First generate a VarInfo using `VarInfo(model)`;
182
182
- Then call `DynamicPPL.init!!(model, v, InitFromParams(...))` to evaluate the model using those parameters.
183
183
184
-
This costs an extra model evaluation at the very beginning to generate the VarInfo, but subsequent evaluations will be efficient.
184
+
This requires you to pay a one-time cost at the very beginning to generate the VarInfo, but subsequent evaluations will be efficient.
185
+
DynamicPPL uses this approach when implementing functions such as `predict(model, chain)`.
185
186
186
-
For example, this is how functions like `predict(model, chain)` are implemented.
187
+
::: {.callout-tip}
188
+
If you want to avoid even the first model evaluation, you will need to read on to the 'Advanced' section below.
189
+
However, for most applications this should not necessary.
190
+
:::
187
191
188
-
## `unflatten`
192
+
## Parameters in the form of Vectors
189
193
190
194
In general, one problem with `init!!` is that it is often slower than `evaluate!!`.
191
195
This is primarily because it does more work: it has to not only read from the provided parameters, but also overwrite existing values in the VarInfo.
@@ -237,7 +241,7 @@ The inverse operation of `unflatten` is `DynamicPPL.getindex_internal(v, :)`:
237
241
DynamicPPL.getindex_internal(v_unflattened, :)
238
242
```
239
243
240
-
## LogDensityFunction
244
+
## `LogDensityFunction`
241
245
242
246
There is one place where `unflatten` is (unfortunately) quite indispensable, namely, the implementation of the LogDensityProblems.jl interface for Turing models.
0 commit comments