-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Adding logdet #1777
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
Adding logdet #1777
Conversation
Thanks @bhargavvader! Can we just copy the test from the PR? |
pymc3/theanof.py
Outdated
matrix M, log(abs(det(M))), on CPU. Avoids det(M) overflow/ | ||
underflow. | ||
|
||
Note: Once PR #3959 in the Theano repo is merged, this must be removed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should add specific link to PR and also mention the original author.
Moreover, would be great if this functionality would already be used in ADVI as part of this PR. |
pymc3/tests/test_theanof.py
Outdated
@@ -18,6 +19,33 @@ def integers_ndim(ndim): | |||
yield np.ones((2,) * ndim) * i | |||
i += 1 | |||
|
|||
class TestLogDet(unittest.TestCase): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should inherit from SeededTest
Addressed code comments. |
https://github.com/pymc-devs/pymc3/blob/master/pymc3/distributions/multivariate.py#L116 here is where we want to use it. Was wrong about ADVI. |
Cool - so would that be doing Also, the tests are failing, but I think it's related to #1773. The |
Yes, that looks right. |
@twiecki , made the changes to |
pymc3/distributions/multivariate.py
Outdated
@@ -12,6 +12,8 @@ | |||
from theano.tensor.nlinalg import det, matrix_inverse, trace | |||
|
|||
import pymc3 as pm | |||
|
|||
from pycm3.theanof import logdet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo pymc3
@bhargavvader Make sure that unittests (specifically the distribution ones) still pass locally. |
I've corrected the typo - had a few doubts about running the tests locally, working on it now. |
This is great. I want a second set of eyes on this: @ColCarroll @taku-y @fonnesbeck do you have time to take a look? |
Update: when I ran
|
A recent PR added nose-parametrized. You can pip install it.
…On Thu, Feb 16, 2017, 7:28 AM Bhargav Srinivasa ***@***.***> wrote:
Update: when I ran nosetests pymc3/tests, there were 9 errors. Both
test_distributions.py and test_theanof.py failed with ImportError: No
module named nose_parameterized. The other fails were with
pymc3.tests.test_stats.TestStats which I reckon is unrelated.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1777 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ACMHEDLOizyA7oC85bTf1QYIOs7tBKwHks5rdEDcgaJpZM4L_PRt>
.
|
All of |
What makes you say they don't run on travis? Another thing occurred to me: missing GPU support. We're inducing a blocker to run any model with MvNormal on the GPU. I see two solutions:
|
Oh my bad - I noticed that one of the travis checks doesn't include them, but the other one does. About GPU support, I would be up to the task, but not immediately - I am caught up with some school work and can't devote too much time at the moment. We can add a flag for the moment if that makes sense. Would it be a log, or a warning? |
I'm happy with merging this. Perhaps GPU support can be added after the Theano PR is merged? |
Here's what I think we should do:
|
@twiecki Is that something we think we'd use again? If so, maybe write a decorator that could be added and removed whenever we have (temporary) GPU compatibility issues. |
@fonnesbeck Good point. We could put that logic into the Op itself maybe. We might also want to automatically switch in case of GPU and give a warning. |
I looked over the code and it looks good to me. It would be nice to merge this PR even if GPU has not been supported yet. |
Cool - I've added the flag and the warning. I agree with the idea of having a decorator for GPU compatibility issues but I'd rather take it up in a new PR (if we do want it). |
pymc3/distributions/multivariate.py
Outdated
@@ -113,7 +123,7 @@ def logp(self, value): | |||
delta = value - mu | |||
k = tau.shape[0] | |||
|
|||
result = k * tt.log(2 * np.pi) + tt.log(1. / det(tau)) | |||
result = k * tt.log(2 * np.pi) - logdet(tau) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to actually check if gpu_compat is true and use the previous statement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missed it before - just fixed now.
pymc3/distributions/multivariate.py
Outdated
@@ -113,7 +124,10 @@ def logp(self, value): | |||
delta = value - mu | |||
k = tau.shape[0] | |||
|
|||
result = k * tt.log(2 * np.pi) + tt.log(1. / det(tau)) | |||
if self.gpu_compat is False: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can just do if self.gpu_compat: ... else: ...
Merging once tests pass. |
👍 |
@bhargavvader I just realized that I gave bad advice with placing |
pymc3/distributions/multivariate.py
Outdated
if gpu_compat is False: | ||
result = k * tt.log(2 * np.pi) - logdet(tau) | ||
elif gpu_compat is True: | ||
result = k * tt.log(2 * np.pi) + tt.log(1. / det(tau)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
result = k * tt.log(2 * np.pi) - tt.log(det(tau))
maybe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or maybe even move the previous part on top and only do result -= logdet(tau)
o = theano.tensor.scalar(dtype=x.dtype) | ||
return Apply(self, [x], [o]) | ||
|
||
def perform(self, node, inputs, outputs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Signature of overriden method changed, should be perform(self, node, inputs, output_storage, params=None)
for consistency
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's not crucial thing, so you can take it in account only if you decide moving logdet
to math.py
I wouldn't mind changing it over to |
Great! Yes, separate PR, also see @ferrine's point. if you have an idea for
the decorator sure but I don't think it's high priority.
…On Feb 18, 2017 8:59 AM, "Bhargav Srinivasa" ***@***.***> wrote:
I wouldn't mind changing it over to math.py. - should I open a different
PR, or will you undo this one? I also wanted to know if there would be
interest for a non-GPU compatible decorator like @fonnesbeck
<https://github.com/fonnesbeck> was talking about - in that case I can
open the 2 PRs in a few days.
—
You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub
<#1777 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AApJmESiHfB9zPJ-AK1dfytV7amZPX0zks5rdqTHgaJpZM4L_PRt>
.
|
@@ -113,7 +124,10 @@ def logp(self, value): | |||
delta = value - mu | |||
k = tau.shape[0] | |||
|
|||
result = k * tt.log(2 * np.pi) + tt.log(1. / det(tau)) | |||
if self.gpu_compat: | |||
result = k * tt.log(2 * np.pi) + tt.log(1. / det(tau)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the first term can be moved up top, then the if-clause just does -logdet or -tt.log(det(tau)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use this code in future, it worked for me
Seems like travis is unhappy about this all of a sudden:
Can you take a look @bhargavvader |
x = tt.matrix()
x ** 2 fails with the same error x = tt.matrix()
x.tag.test_value = np.array([[1,1], [2,2]])
x ** 2 not |
Uh oh. I'll have a look at this. |
I'm a little confused about which This is similar to an issue raised by @fonnesbeck , where the solution is just to delete the cache ( |
@twiecki , what's the status of this? Is it still failing? |
Seems OK, not sure what caused this. |
This is with regard to #1012.
The code is copy pasted from Theano PR #3959 as suggested in the issue, with the function renamed to
logdet
.Should there be tests made for this as well?