probcomp / Gen.jl

A general-purpose probabilistic programming system with programmable inference
https://gen.dev
Apache License 2.0
1.8k stars 160 forks source link

Gen.sample_unweighted_traces fails if log_weights == NaN #117

Closed mbhurley1958 closed 5 years ago

mbhurley1958 commented 5 years ago

When running the particle filter code with probabilities that can generate -Inf log_weights, repeated running eventually appears to produce NaN values. Calling Gen.sample_unweighted_traces() then fails. The fast fix is to replace NaN weights with -Inf values before calling the function. There may be more subtle modifications that could be made in the Gen code to avoid this error.

ArgumentError: Categorical: the condition isprobvec(p) is not satisfied.

Stacktrace: [1] macro expansion at /Users/mi13017/.julia/packages/Distributions/WHjOk/src/utils.jl:6 [inlined] [2] Type at /Users/mi13017/.julia/packages/Distributions/WHjOk/src/univariate/discrete/categorical.jl:27 [inlined] [3] Type at /Users/mi13017/.julia/packages/Distributions/WHjOk/src/univariate/discrete/categorical.jl:38 [inlined] [4] random(::Gen.Categorical, ::Array{Float64,1}) at /Users/mi13017/.julia/packages/Gen/hqA7O/src/modeling_library/categorical.jl:21 [5] Categorical at /Users/mi13017/.julia/packages/Gen/hqA7O/src/modeling_library/categorical.jl:24 [inlined] [6] sample_unweighted_traces(::Gen.ParticleFilterState{Gen.DynamicDSLTrace}, ::Int64) at /Users/mi13017/.julia/packages/Gen/hqA7O/src/inference/particle_filter.jl:67

fsaad commented 5 years ago

Hi @mbhurley1958 thanks for the report.

NaN will show up whenever all the particles have log weight equal to -Inf, for example when normalizing: https://github.com/probcomp/Gen/blob/afeeddd6e1bea2af78f5c86d9996c26c8d49e005/src/inference/particle_filter.jl#L8-L12

One possibility is to alert the user by raising an error to indicate that all particles have log weight -Inf, since the semantics of particle filtering are ill-defined in this case.

Replacing NaN with -Inf is also possible from user's end, but I would be very weary of the inference results since it indicates there is quite likely a problem with the model and/or the proposal that needs further investigation. The excerpt of the code that produced this error would be helpful to zero in on the cause.

alex-lew commented 5 years ago

When running the particle filter code with probabilities that can generate -Inf log_weights

Do you think you could give an example? In Gen, we require that the support of a random choice associated with a particular address be constant:

https://probcomp.github.io/Gen/dev/ref/modeling/#Choices-should-have-constant-support-1

As in the example at the above link, a categorical draw whose support depends on the current state can use a dynamic address that also depends on the current state.

I believe that satisfying this requirement should in general mean that -Inf weights don't occur (so long as you don't specify observations that are impossible under the model).

That said, we could certainly surface better error messages to the user when -Inf weights do arise. And in some cases, the above requirement may be too restrictive -- when you have enough particles, -Inf weights can sometimes be useful. Thanks for the report!

mbhurley1958 commented 5 years ago

Feras, Alex,

I'm at Lincoln Lab, so it can be problematic to simple send out software. I have put a sample file in the MIT GitHub repository that Michael Yee had set up for collaboration. Marco should have access and can pull the file from there so that those in the collaboration with us can examine it: https://github.mit.edu/INFERENCE/inference-collab/

The directory is: https://github.mit.edu/INFERENCE/inference-collab/tree/master/bug_example/

The file is: Search_PF_NaN.ipynb

The model is a Bayesian search model where a sensor moves around a 2D space looking for a target. If the target is in the field of view (FOV) of the sensor, it is a bernoulli draw of 1.0, otherwise 0.0. This is most likely generating -Inf for weights of particles in the FOV when the true particle is not in the FOV. Maybe there is something going on that causes an NaN when particles previously in a FOV are in the FOV at a later time step?

Not all particle weights are NaN or -Inf. There are still some reasonable particle weights. I don't believe that I'm changing random choices (but could be wrong).

I know that the bernoulli draw with a probability of 1 or 0 is an edge case, but didn't expect problems.