Inference results postprocessing
The infer function allows users to control how inference results are postprocessed via the postprocess keyword argument.
Internally, the inference engine operates on Marginal wrapper types that carry both the underlying distribution and any associated annotation data. The postprocessing step determines whether these wrappers are preserved or stripped from the final result.
Default behavior
The default postprocessing strategy depends on whether annotations are enabled:
- Without annotations (
annotations = nothing, the default): the strategy isUnpackMarginalPostprocess. Since no annotation data is attached, theMarginalwrapper is removed and the result contains the underlying distribution directly (e.g., aNormalorBetadistribution). - With annotations (e.g.,
annotations = LogScaleAnnotations()): the strategy isNoopPostprocess. TheMarginalwrapper is preserved so that annotation data remains accessible viaReactiveMP.getannotations.
You can always override the default by passing postprocess = ... explicitly to infer.
Available strategies
RxInfer.inference_postprocess — Function
inference_postprocess(strategy, result)Postprocesses the result of the inference procedure according to the given strategy. The result is typically a Marginal or a collection of Marginals.
The infer function selects a default strategy automatically based on whether annotations are enabled:
- When
annotations = nothing(the default), the strategy isUnpackMarginalPostprocess, which strips theMarginalwrapper and returns the underlying distribution directly. - When annotations are provided, the strategy is
NoopPostprocess, which preserves theMarginalwrapper so that annotation data remains accessible viaReactiveMP.getannotations.
You can override this default by passing a custom postprocess argument to infer. See Inference results postprocessing for more details.
RxInfer.UnpackMarginalPostprocess — Type
UnpackMarginalPostprocessA postprocessing strategy that removes the Marginal wrapper type from the inference result, returning the underlying distribution directly. This is the default strategy when no annotations are enabled, since the Marginal wrapper carries no extra information in that case.
See also: NoopPostprocess, inference_postprocess
RxInfer.NoopPostprocess — Type
NoopPostprocessA postprocessing strategy that preserves the inference result as-is, keeping the Marginal wrapper intact. This is the default strategy when annotations are enabled, so that annotation data attached to each marginal remains accessible via ReactiveMP.getannotations.
See also: UnpackMarginalPostprocess, inference_postprocess
Custom postprocessing step
To implement a custom postprocessing strategy, define a new type and implement the inference_postprocess method for it:
using RxInfer
struct CustomPostprocess end
# For demonstration purposes our postprocessing step simply stringifies the result
RxInfer.inference_postprocess(::CustomPostprocess, result::Marginal) = string(ReactiveMP.getdata(result))Now, we can use the postprocessing step in the infer function:
@model function beta_bernoulli(y)
θ ~ Beta(1, 1)
y ~ Bernoulli(θ)
end
result = infer(
model = beta_bernoulli(),
data = (y = 1.,),
postprocess = CustomPostprocess()
)
result.posteriors[:θ] # should be a `String`"Beta{Float64}(α=2.0, β=1.0)"result.posteriors[:θ] isa Stringtrue