John Pearson
DukeML group meeting
2-18-16
<img src="http://pearsonlab.github.io/images/plab_logo_dark.svg" width="300", align="left">
In [4]:
push!(LOAD_PATH, "/Users/jmxp/code/VinDsl.jl/src")
using VinDsl
using Distributions
In [6]:
dims = (20, 6)
μ[j] ~ Normal(zeros(dims[2]), ones(dims[2]))
τ[j] ~ Gamma(1.1 * ones(dims[2]), ones(dims[2]))
μ0[j] ~ Const(zeros(dims[2]))
y[i, j] ~ Const(rand(dims));
~ defines a node
In [8]:
f = @factor LogNormalFactor y μ τ;
In future:
In [ ]:
@pmodel begin
y ~ Normal(μ, τ)
end
New factor types can be defined with yet another macro:
In [ ]:
@deffactor LogNormalFactor [x, μ, τ] begin
-(1/2) * ((E(τ) * ( V(x) + V(μ) + (E(x) - E(μ))^2 ) + log(2π) + Elog(τ)))
end
@deffactor LogGammaCanonFactor [x, α, β] begin
(E(α) - 1) * Elog(x) - E(β) * E(x) + E(α) * E(β) - Eloggamma(α)
end
E(x) $\equiv \mathbb{E}[X]$, V(x) $\equiv \textrm{cov}[X]$, etc. VinDsl generates a value(f) function that handles indices appropriately and sums over the dimensions of the array
In [10]:
dims = (20, 6)
# note: it won't matter much how we initialize here
μ[j] ~ Normal(zeros(dims[2]), ones(dims[2]))
τ[j] ~ Gamma(1.1 * ones(dims[2]), ones(dims[2]))
μ0[j] ~ Const(zeros(dims[2]))
τ0[j] ~ Const(2 * ones(dims[2]))
a0[j] ~ Const(1.1 * ones(dims[2]))
b0[j] ~ Const(ones(dims[2]))
y[i, j] ~ Const(rand(dims))
# make factors
obs = @factor LogNormalFactor y μ τ
μ_prior = @factor LogNormalFactor μ μ0 τ0
τ_prior = @factor LogGammaCanonFactor τ a0 b0
m = VBModel([μ, τ, μ0, τ0, a0, b0, y], [obs, μ_prior, τ_prior]);
So this is easy: i is inner:
In [ ]:
d = 5
μ[i] ~ MvNormalCanon(zeros(d), diagm(ones(d)))
Λ[i, i] ~ Wishart(float(d), diagm(ones(d)))
But here, i is inner for $\mu$ but not for $\tau$. In any factor combining these two, $\tau$ will be treated like a vector because it matches an inner index for some node:
In [ ]:
μ[i] ~ MvNormalCanon(zeros(d), diagm(ones(d)))
τ[i] ~ Gamma(1.1 * ones(d), ones(d))
In [11]:
x ~ Normal(rand(), rand())
y ~ Normal(rand(), rand())
@expandE E(x.data[1] + y.data[1])
Out[11]:
In [13]:
macroexpand(:(@expandE E(x + y * z + 5)))
Out[13]:
Note: assumes all nodes are independent!
In [ ]:
@pmodel begin
x[i, k] ~ ...
y[j, k] ~ ...
z := sum(x, i) + sum(y, j)
end
In [ ]:
@defnaturals LogNormalFactor μ Normal begin
Ex, Eτ = E(x), E(τ)
(Ex * Eτ, -Eτ/2)
end
@defnaturals LogNormalFactor τ Gamma begin
v = V(x) + V(μ) + (E(x) - E(μ))^2
(1/2, v/2)
end
@qmodel and @pmodel, := for ExprNodes