Skip to content

Commit 82cf9f7

Browse files
authored
Merge pull request #67 from probcomp/20190203-marcoct-names
20190203 marcoct names
2 parents 2ade766 + 9470877 commit 82cf9f7

File tree

111 files changed

+3273
-4046
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+3273
-4046
lines changed

docs/make.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ makedocs(
1313
"Probability Distributions" => "ref/distributions.md",
1414
"Built-in Modeling Language" => "ref/modeling.md",
1515
"Generative Function Combinators" => "ref/combinators.md",
16-
"Assignments" => "ref/assignments.md",
16+
"Choice Maps" => "ref/choice_maps.md",
1717
"Selections" => "ref/selections.md",
1818
"Optimizing Trainable Parameters" => "ref/parameter_optimization.md",
1919
"Inference Library" => "ref/inference.md",

docs/src/getting_started.md

+8-8
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,16 @@ Let's write a short Gen program that does Bayesian linear regression: given a se
1919

2020
There are three main components to a typical Gen program.
2121

22-
First, we define a _generative model_: a Julia function, extended with some extra syntax, that, conceptually, simulates a fake dataset. The model below samples `slope` and `intercept` parameters, and then for each of the x-coordinates that it accepts as input, samples a corresponding y-coordinate. We name the random choices we make with `@addr`, so we can refer to them in our inference program.
22+
First, we define a _generative model_: a Julia function, extended with some extra syntax, that, conceptually, simulates a fake dataset. The model below samples `slope` and `intercept` parameters, and then for each of the x-coordinates that it accepts as input, samples a corresponding y-coordinate. We name the random choices we make with `@trace`, so we can refer to them in our inference program.
2323

2424
```julia
2525
using Gen
2626

2727
@gen function my_model(xs::Vector{Float64})
28-
slope = @addr(normal(0, 2), :slope)
29-
intercept = @addr(normal(0, 10), :intercept)
28+
slope = @trace(normal(0, 2), :slope)
29+
intercept = @trace(normal(0, 10), :intercept)
3030
for (i, x) in enumerate(xs)
31-
@addr(normal(slope * x + intercept, 1), "y-$i")
31+
@trace(normal(slope * x + intercept, 1), "y-$i")
3232
end
3333
end
3434
```
@@ -42,14 +42,14 @@ The inference program below takes in a data set, and runs an iterative MCMC algo
4242
function my_inference_program(xs::Vector{Float64}, ys::Vector{Float64}, num_iters::Int)
4343
# Create a set of constraints fixing the
4444
# y coordinates to the observed y values
45-
constraints = DynamicAssignment()
45+
constraints = choicemap()
4646
for (i, y) in enumerate(ys)
4747
constraints["y-$i"] = y
4848
end
4949

5050
# Run the model, constrained by `constraints`,
5151
# to get an initial execution trace
52-
(trace, _) = initialize(my_model, (xs,), constraints)
52+
(trace, _) = generate(my_model, (xs,), constraints)
5353

5454
# Iteratively update the slope then the intercept,
5555
# using Gen's metropolis_hastings operator.
@@ -60,8 +60,8 @@ function my_inference_program(xs::Vector{Float64}, ys::Vector{Float64}, num_iter
6060

6161
# From the final trace, read out the slope and
6262
# the intercept.
63-
assmt = get_assmt(trace)
64-
return (assmt[:slope], assmt[:intercept])
63+
choices = get_choices(trace)
64+
return (choices[:slope], choices[:intercept])
6565
end
6666
```
6767

Original file line numberDiff line numberDiff line change
@@ -1,52 +1,52 @@
1-
# Assignments
1+
# Choice Maps
22

33
Maps from the addresses of random choices to their values are stored in associative tree-structured data structures that have the following abstract type:
44
```@docs
5-
Assignment
5+
ChoiceMap
66
```
77

8-
Assignments are constructed by users to express observations and/or constraints on the traces of generative functions.
9-
Assignments are also returned by certain Gen inference methods, and are used internally by various Gen inference methods.
8+
Choice maps are constructed by users to express observations and/or constraints on the traces of generative functions.
9+
Choice maps are also returned by certain Gen inference methods, and are used internally by various Gen inference methods.
1010

11-
Assignments provide the following methods:
11+
Choice maps provide the following methods:
1212
```@docs
1313
has_value
1414
get_value
15-
get_subassmt
15+
get_submap
1616
get_values_shallow
17-
get_subassmts_shallow
17+
get_submaps_shallow
1818
to_array
1919
from_array
2020
address_set
2121
```
2222
Note that none of these methods mutate the assignment.
2323

24-
Assignments also provide `Base.isempty`, which tests of there are no random
24+
Choice maps also provide `Base.isempty`, which tests of there are no random
2525
choices in the assignment, and `Base.merge`, which takes two assignments, and
2626
returns a new assignment containing all random choices in either assignment.
2727
It is an error if the assignments both have values at the same address, or if
2828
one assignment has a value at an address that is the prefix of the address of a
2929
value in the other assignment.
3030

3131

32-
## Dynamic Assignment
32+
## Dynamic Choice Map
3333

34-
One concrete assignment type is `DynamicAssignment`, which is mutable.
35-
Users construct `DynamicAssignments` and populate them for use as observations or constraints, e.g.:
34+
One concrete assignment type is `DynamicChoiceMap`, which is mutable.
35+
Users construct `DynamicChoiceMaps` and populate them for use as observations or constraints, e.g.:
3636
```julia
37-
assmt = DynamicAssignment()
38-
assmt[:x] = true
39-
assmt["foo"] = 1.25
40-
assmt[:y => 1 => :z] = -6.3
37+
choices = choicemap()
38+
choices[:x] = true
39+
choices["foo"] = 1.25
40+
choices[:y => 1 => :z] = -6.3
4141
```
4242

43-
There is also a constructor for `DynamicAssignment` that takes initial (address, value) pairs:
43+
There is also a constructor for `DynamicChoiceMap` that takes initial (address, value) pairs:
4444
```julia
45-
assmt = DynamicAssignment((:x, true), ("foo", 1.25), (:y => 1 => :z, -6.3))
45+
choices = choicemap((:x, true), ("foo", 1.25), (:y => 1 => :z, -6.3))
4646
```
4747

4848
```@docs
49-
DynamicAssignment
49+
choicemap
5050
set_value!
51-
set_subassmt!
51+
set_submap!
5252
```

docs/src/ref/combinators.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ In the schematic below, the kernel is denoted ``\mathcal{G}_{\mathrm{k}}``.
2121
For example, consider the following generative function, which makes one random choice at address `:z`:
2222
```julia
2323
@gen function foo(x1::Float64, x2::Float64)
24-
y = @addr(normal(x1 + x2, 1.0), :z)
24+
y = @trace(normal(x1 + x2, 1.0), :z)
2525
return y
2626
end
2727
```
@@ -31,7 +31,7 @@ bar = Map(foo)
3131
```
3232
We can then obtain a trace of `bar`:
3333
```julia
34-
(trace, _) = initialize(bar, ([0.0, 0.5], [0.5, 1.0]))
34+
(trace, _) = generate(bar, ([0.0, 0.5], [0.5, 1.0]))
3535
```
3636
This causes `foo` to be invoked twice, once with arguments `(0.0, 0.5)` in address namespace `1` and once with arguments `(0.5, 1.0)` in address namespace `2`.
3737
If the resulting trace has random choices:
@@ -95,7 +95,7 @@ The initial state is denoted ``y_0``, the number of applications is ``n``, and t
9595
For example, consider the following kernel, with state type `Bool`, which makes one random choice at address `:z`:
9696
```julia
9797
@gen function foo(t::Int, y_prev::Bool, z1::Float64, z2::Float64)
98-
y = @addr(bernoulli(y_prev ? z1 : z2), :y)
98+
y = @trace(bernoulli(y_prev ? z1 : z2), :y)
9999
return y
100100
end
101101
```
@@ -105,7 +105,7 @@ bar = Map(foo)
105105
```
106106
We can then obtain a trace of `bar`:
107107
```julia
108-
(trace, _) = initialize(bar, (5, false, 0.05, 0.95))
108+
(trace, _) = generate(bar, (5, false, 0.05, 0.95))
109109
```
110110
This causes `foo` to be invoked five times.
111111
The resulting trace may contain the following random choices:

docs/src/ref/gfi.md

+34-34
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ There are various kinds of generative functions, which are represented by concre
1212
For example, the [Built-in Modeling Language](@ref) allows generative functions to be constructed using Julia function definition syntax:
1313
```julia
1414
@gen function foo(a, b)
15-
if @addr(bernoulli(0.5), :z)
15+
if @trace(bernoulli(0.5), :z)
1616
return a + b + 1
1717
else
1818
return a + b
@@ -34,18 +34,18 @@ We represent the randomness used during an execution of a generative function as
3434
In this section, we assume that random choices are discrete to simplify notation.
3535
We say that two random choice maps ``t`` and ``s`` **agree** if they assign the same value for any address that is in both of their domains.
3636

37-
Generative functions may also use **non-addressed randomness**, which is not included in the map ``t``.
38-
However, the state of non-addressed random choices *is* maintained by the trace internally.
39-
We denote non-addressed randomness by ``r``.
40-
Non-addressed randomness is useful for example, when calling black box Julia code that implements a randomized algorithm.
37+
Generative functions may also use **untraced randomness**, which is not included in the map ``t``.
38+
However, the state of untraced random choices *is* maintained by the trace internally.
39+
We denote untraced randomness by ``r``.
40+
Untraced randomness is useful for example, when calling black box Julia code that implements a randomized algorithm.
4141

4242
The observable behavior of every generative function is defined by the following mathematical objects:
4343

4444
### 1. Input type
4545
The set of valid argument tuples to the function, denoted ``X``.
4646

4747
### 2. Probability distribution family
48-
A family of probability distributions ``p(t, r; x)`` on maps ``t`` from random choice addresses to their values, and non-addressed randomness ``r``, indexed by arguments ``x``, for all ``x \in X``.
48+
A family of probability distributions ``p(t, r; x)`` on maps ``t`` from random choice addresses to their values, and untraced randomness ``r``, indexed by arguments ``x``, for all ``x \in X``.
4949
Note that the distribution must be normalized:
5050
```math
5151
\sum_{t, r} p(t, r; x) = 1 \;\; \mbox{for all} \;\; x \in X
@@ -55,14 +55,14 @@ We use ``p(t; x)`` to denote the marginal distribution on the map ``t``:
5555
```math
5656
p(t; x) := \sum_{r} p(t, r; x)
5757
```
58-
And we denote the conditional distribution on non-addressed randomness ``r``, given the map ``t``, as:
58+
And we denote the conditional distribution on untraced randomness ``r``, given the map ``t``, as:
5959
```math
6060
p(r; x, t) := p(t, r; x) / p(t; x)
6161
```
6262

6363
### 3. Return value function
6464
A (deterministic) function ``f`` that maps the tuple ``(x, t)`` of the arguments and the random choice map to the return value of the function (which we denote by ``y``).
65-
Note that the return value cannot depend on the non-addressed randomness.
65+
Note that the return value cannot depend on the untraced randomness.
6666

6767
### 4. Internal proposal distribution family
6868
A family of probability distributions ``q(t; x, u)`` on maps ``t`` from random choice addresses to their values, indexed by tuples ``(x, u)`` where ``u`` is a map from random choice addresses to values, and where ``x`` are the arguments to the function.
@@ -76,7 +76,7 @@ p(t; x) > 0 \mbox{ if and only if } q(t; x, u) > 0 \mbox{ for all } u \mbox{ whe
7676
```math
7777
q(t; x, u) > 0 \mbox{ implies that } u \mbox{ and } t \mbox{ agree }.
7878
```
79-
There is also a family of probability distributions ``q(r; x, t)`` on non-addressed randomness, that satisfies:
79+
There is also a family of probability distributions ``q(r; x, t)`` on untraced randomness, that satisfies:
8080
```math
8181
q(r; x, t) > 0 \mbox{ if and only if } p(r; x, t) > 0
8282
```
@@ -107,7 +107,7 @@ get_retval
107107

108108
The map ``t`` from addresses of random choices to their values:
109109
```@docs
110-
get_assmt
110+
get_choices
111111
```
112112

113113
The log probability that the random choices took the values they did:
@@ -128,13 +128,13 @@ There are several methods that take a trace of a generative function as input an
128128
We will illustrate these methods using the following generative function:
129129
```julia
130130
@gen function foo()
131-
val = @addr(bernoulli(0.3), :a)
132-
if @addr(bernoulli(0.4), :b)
133-
val = @addr(bernoulli(0.6), :c) && val
131+
val = @trace(bernoulli(0.3), :a)
132+
if @trace(bernoulli(0.4), :b)
133+
val = @trace(bernoulli(0.6), :c) && val
134134
else
135-
val = @addr(bernoulli(0.1), :d) && val
135+
val = @trace(bernoulli(0.1), :d) && val
136136
end
137-
val = @addr(bernoulli(0.7), :e) && val
137+
val = @trace(bernoulli(0.7), :e) && val
138138
return val
139139
end
140140
```
@@ -151,22 +151,22 @@ Suppose we have a trace (`trace`) with initial choices:
151151
```
152152
Note that address `:d` is not present because the branch in which `:d` is sampled was not taken because random choice `:b` had value `true`.
153153

154-
### Force Update
154+
### Update
155155
```@docs
156-
force_update
156+
update
157157
```
158-
Suppose we run [`force_update`](@ref) on the example `trace`, with the following constraints:
158+
Suppose we run [`update`](@ref) on the example `trace`, with the following constraints:
159159
```
160160
161161
├── :b : false
162162
163163
└── :d : true
164164
```
165165
```julia
166-
constraints = DynamicAssignment((:b, false), (:d, true))
167-
(new_trace, w, discard, _) = force_update((), noargdiff, trace, constraints)
166+
constraints = choicemap((:b, false), (:d, true))
167+
(new_trace, w, _, discard) = update(trace, (), noargdiff, constraints)
168168
```
169-
Then `get_assmt(new_trace)` will be:
169+
Then `get_choices(new_trace)` will be:
170170
```
171171
172172
├── :a : false
@@ -192,20 +192,20 @@ p(t; x') = 0.7 × 0.6 × 0.1 × 0.7 = 0.0294\\
192192
w = \log p(t'; x')/p(t; x) = \log 0.0294/0.0784 = \log 0.375
193193
```
194194

195-
### Free Update
195+
### Regenerate
196196
```@docs
197-
free_update
197+
regenerate
198198
```
199-
Suppose we run [`free_update`](@ref) on the example `trace`, with selection `:a` and `:b`:
199+
Suppose we run [`regenerate`](@ref) on the example `trace`, with selection `:a` and `:b`:
200200
```julia
201-
(new_trace, w, _) = free_update((), noargdiff, trace, select(:a, :b))
201+
(new_trace, w, _) = regenerate(trace, (), noargdiff, select(:a, :b))
202202
```
203203
Then, a new value for `:a` will be sampled from `bernoulli(0.3)`, and a new value for `:b` will be sampled from `bernoulli(0.4)`.
204204
If the new value for `:b` is `true`, then the previous value for `:c` (`false`) will be retained.
205205
If the new value for `:b` is `false`, then a new value for `:d` will be sampled from `bernoulli(0.7)`.
206206
The previous value for `:c` will always be retained.
207207
Suppose the new value for `:a` is `true`, and the new value for `:b` is `true`.
208-
Then `get_assmt(new_trace)` will be:
208+
Then `get_choices(new_trace)` will be:
209209
```
210210
211211
├── :a : true
@@ -219,9 +219,9 @@ Then `get_assmt(new_trace)` will be:
219219
The weight (`w`) is ``\log 1 = 0``.
220220

221221

222-
### Extend
222+
### Extend update
223223
```@docs
224-
extend
224+
extend_update
225225
```
226226

227227
### Argdiffs
@@ -270,8 +270,8 @@ This static property of the generative function is reported by `accepts_output_g
270270
```@docs
271271
has_argument_grads
272272
accepts_output_grad
273-
backprop_params
274-
backprop_trace
273+
accumulate_param_gradients!
274+
choice_gradients
275275
get_params
276276
```
277277

@@ -320,19 +320,19 @@ Then, the argument tuple passed to e.g. [`initialize`](@ref) will have two eleme
320320
NOTE: Be careful to distinguish between arguments to the generative function itself, and arguments to the constructor of the generative function.
321321
For example, if you have a generative function type that is parametrized by, for example, modeling DSL code, this DSL code would be a parameter of the generative function constructor.
322322

323-
### Decide what the addressed random choices (if any) will be
323+
### Decide what the traced random choices (if any) will be
324324
Remember that each random choice is assigned a unique address in (possibly) hierarchical address space.
325325
You are free to design this address space as you wish, although you should document it for users of your generative function type.
326326

327327
### Implement the methods of the interface
328328

329329
- At minimum, you need to implement all methods under the [`Traces`](@ref) heading (e.g. [`initialize`](@ref), ..)
330330

331-
- To support [`metropolis_hastings`](@ref) or local optimization, or local iterative adjustments to traces, be sure to implement the [`force_update`](@ref) and [`free_update](@ref) methods.
331+
- To support [`metropolis_hastings`](@ref) or local optimization, or local iterative adjustments to traces, be sure to implement the [`update`](@ref) and [`regenerate`](@ref) methods.
332332

333-
- To support gradients of the log probability density with respect to the arguments and/or random choices made by the function, implement the [`backprop_trace`](@ref) method.
333+
- To support gradients of the log probability density with respect to the arguments and/or random choices made by the function, implement the [`choice_gradients`](@ref) method.
334334

335-
- Generative functions can also have trainable parameters (e.g. neural network weights). To support these, implement the [`backprop_params`](@ref) method.
335+
- Generative functions can also have trainable parameters (e.g. neural network weights). To support these, implement the [`accumulate_param_gradients!`](@ref) method.
336336

337337
- To support use of your generative function in custom proposals (instead of just generative models), implement [`assess`](@ref) and [`propose`](@ref) methods.
338338

0 commit comments

Comments
 (0)