Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

semantics of mem is questionable #896

Open
ngoodman opened this issue Feb 14, 2018 · 5 comments
Open

semantics of mem is questionable #896

ngoodman opened this issue Feb 14, 2018 · 5 comments

Comments

@ngoodman
Copy link
Contributor

i think there may be a bug, or at least questionable choice in the semantics of mem. consider:

Infer({method: 'rejection', samples: 100}, function() {
  var memfn = mem(function(buttons) {return uniform(0,1)})
//   memfn('a');
  
  var inner = Infer({method: 'rejection', samples: 100}, function() {
    var p = memfn('a')
    condition(flip(p))
    return flip(p)
  })
  
  return sample(inner)
})

different results are obtained if the memfn('a'); line is uncommented. it does not seem to me like this should happen.

the semantics we converged on for mem in Church was that all of the random sampling (for all inputs to the function) was to be considered as happening where the memoized function was created, even if the sampling was deferred in practice. in webppl it seems that we are breaking this convention, at least when a memoized function crosses an Infer boundary.

(this bug came to light in probmods/probmods2#56)

@daphnab
Copy link

daphnab commented Feb 14, 2018

This issue I reported on the probmods page may also be relevant:

probmods/probmods2#55

my workaround using cache suggests that the semantics for cache are perhaps also not quite working as intended (the documentation suggests that cache should be fully deterministic, but current functioning appears to be consistent with Noah's description of the Church mem semantics above).

@null-a
Copy link
Member

null-a commented Feb 15, 2018

I don't have any good ideas about how to fix this at the moment, but here are a few thoughts on earlier comments:

in webppl it seems that we are breaking this convention, at least when a memoized function crosses an Infer boundary.

@ngoodman is right about the significance if the Infer boundary. This arises because mem is implemented by memoizing the function using WebPPL's global store as a cache. I think this is fine for the case of a single Infer, but in the nested example the result of calling memfn('a') is not automatically shared across executions of the inner model, because Infer arranges for each such execution to have a fresh store.

Adding the call to memfn('a') in the outer model adds the result to the cache before entering Infer, which means that all executions of the inner model see it. (Since each execution of a model by Infer sees the store as it was when Infer was called.)

(the documentation suggests that cache should be fully deterministic, but current functioning appears to be consistent with Noah's description of the Church mem semantics above).

@daphnab It seems there may be some confusion here. The docs are trying to say that cache should only be applied to a deterministic function. If cache is applied to a stochastic function, all bets are off. For example, the use of cache in this model causes exhaustive enumeration to produce different results depending on the strategy used:

var model = function() {
  var f = cache(function() { return flip(); })
  return [f('a'), f('b')].join(',')
}
Infer({model, method: 'enumerate', strategy: 'depthFirst'})

// Depth first:
// Marginal:
//    "true,true" : 0.5
//    "false,false" : 0.25
//    "false,true" : 0.25

// Breadth first:
// Marginal:
//     "true,true" : 0.25
//     "true,false" : 0.25
//     "false,true" : 0.25
//     "false,false" : 0.25

If cache is replaced with mem in the above, then all strategies return the expected distribution.

I imagine that cache only appears to have the desired mem semantics for algorithms that always re-run the entire model, and that when the algorithm uses fancier control flow that will break down.

@daphnab
Copy link

daphnab commented Feb 15, 2018

@null-a thanks for the clarification about cache! In that case, is there currently a way to make an embedded non-parametric inference (as in the original inference about inference chapter examples)? The current work around in the chapter solves the issue by evaluating the a priori likeliest values outside the inner inference (so it's technically not quite correct, since a priori low probability sequences will still not have consistent probabilities assigned to them). My only other solution was to implement my own rejection sampling rather than using Infer but that's obviously also quite limited.

@null-a
Copy link
Member

null-a commented Feb 15, 2018

is there currently a way to make an embedded non-parametric inference

@daphnab I don't have anything better than your solution at the moment I'm afraid.

@ngoodman
Copy link
Contributor Author

i worked around this in ch6 of probmods, by getting rid of mem.

at some point we should find a solution, though this is a pretty unused corner case....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants