I’m testing a simple Gaussian custom node in RxInfer just to make sure I have the syntax correct, but I’m having trouble with the score function for Bethe free energy. My inference()
function runs fine and returns BFE if I use a Gaussian node rather than my custom node. And it runs fine if I use my custom node but set free_energy = false
. If I set free_energy = true
it fails with the following message:
LoadError: MethodError: no method matching score(::ReactiveMP.AverageEnergy, ::Type{Main.RxTest2.MyNode}, ::Type{Val{(:out, :m, :v)}}, ::Tuple{ReactiveMP.Marginal{ReactiveMP.NormalWeightedMeanPrecision{Float64}, Nothing}, ReactiveMP.Marginal{ReactiveMP.PointMass{Float64}, Nothing}, ReactiveMP.Marginal{ReactiveMP.PointMass{Float64}, Nothing}}, ::Nothing)
Closest candidates are:
I’m not sure how the score function is supposed to be specified, or if I am missing something else. Perhaps it needs additional rules, but if so I’m not asked for any when the code runs. Any ideas, @bvdmitri or others? Code is below.
struct MyNode end
@node MyNode Stochastic [out, m, v]
@rule MyNode(:out, Marginalisation) (
q_m::PointMass,
q_v::PointMass,
) = begin
m = mean(q_m)
W = 1. / mean(q_v)
return NormalWeightedMeanPrecision(m* W, W)
end
# --------------------------------------------------------------------------------------------------
@model function ref_model()
m_x = datavar(Float64)
v_x = datavar(Float64)
x = randomvar()
#x ~ NormalMeanVariance(m_x, v_x) # this works and gives BFE
x ~ MyNode(m_x, v_x) # does not give BFE
x ~ NormalMeanVariance(0.0, 100000.)
return (x, )
end
# --------------------------------------------------------------------------------------------------
result = inference(
data = (
m_x = 10.,
v_x = 1.,
),
model = ref_model(),
initmarginals = (
x = NormalMeanVariance(0.0, huge),
),
free_energy = true,
returnvars = (
x = KeepLast(),
),
)
x_ = mean.(result.posteriors[:x])
println(x_)
As a suggestion, perhaps this simple test case might be a good addition to the documentation, as it might help users get stared with custom nodes. I’ve looked at the documentation and at the ReactiveMP code for a Gaussian node and associated rules, but it’s not clear to me what the bare minimum code is for creating a simple Gaussian custom node that returns BFE.