Prototype debugging helper method check_bounds
#4472
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is a very early draft for a helper debugging method
check_bounds
that tries to parse out to the user any explicit variable bounds that seem to be violated at model.test_point. Here is a minimal example (more below):check_bounds
works by identifying the bounds introduced by thedist_math::bound
method and testing each of the nested logical conditions that may trigger the bound. One nested logical condition is tested at a time by disabling all the remaining ones in atheano.clone
of the switch bound variable.I would really appreciate tips in the following standing issues / limitations:
sd
ofHalfNormal
since it involvesx ~ Normal
, but when the input is not a variable, it can be less clear where it's coming from.Add custom logic to parse BinaryBitOps and more. Right now, the algorithm only attempts to test theano LogicalComparison operations and ignores any
BinaryBitOp
such astt.and
andtt.or
comparisons or aggregating operations such astt.all
andtt.any
.More robust masking of good values.
check_bounds
tries to mask values that are probably not responsible for the bound violations. The hack I implemented to do this looks very fragile to me.More clean way of disabling / enabling the logical operators? I am using
theano.clone
and disabling logical comparisons by replacing them withtt.eq(inputs[0], inputs[0])
so that it always evaluates to True and output shapes remain unaffected (or so I hope). I would love to hear about more idiomatic approaches to this.What kind of output would be most useful? Print statements, Pandas DataFrame or something Else?
Work with implicit bounds, which are sometimes used directly in the logp / logcdf expression or in helper functions such as
dist_math::logpow
. I first tried to implement a more general algorithm that looked for anytt.switch
leading to-inf
and not only those added explicitly by thebound
function. This proved much more challenging as often there are nested switches and the simplistic tests above could not handle this. Also aggregating functions such astt.all
make a general approach even more difficult. However, I see no principled reason why such information cannot be extracted from a theano graph, so if you have any ideas that would be really great!Test with more user examples. I tried to apply this to a few examples from the discourse and it seem to work fine. However, I have not really tried with more complex hierarchical / multivariate models. If you have a model that was particularly challenging to debug, it would be really great if you could share it/ test it in in my branch and see if the output is useful or correct.
Changes for V4.0.0. I think most of the logic will survive, or it may be even simplified by the transition to Aesara RandomVariables. If you see something that will definitely not work or may be easier to achieve later, that would be useful to know :)
Suggested by #4205