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

fix quantile fn for transformed distribution #544

Merged
merged 1 commit into from
Jan 2, 2020
Merged

Conversation

vafl
Copy link
Contributor

@vafl vafl commented Dec 27, 2019

Description of changes:
Fix quantile function for transformed distribution and minor other improvements.
This reduces memory consumption when calculating quantiles for transformed distribution.

Also minor improvements for forecast methods.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@codecov-io
Copy link

codecov-io commented Dec 27, 2019

Codecov Report

Merging #544 into master will decrease coverage by <.01%.
The diff coverage is 80%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #544      +/-   ##
==========================================
- Coverage   83.16%   83.15%   -0.01%     
==========================================
  Files         177      177              
  Lines        9864     9869       +5     
==========================================
+ Hits         8203     8207       +4     
- Misses       1661     1662       +1
Impacted Files Coverage Δ
...c/gluonts/distribution/transformed_distribution.py 95.29% <100%> (+0.17%) ⬆️
src/gluonts/model/forecast.py 71.92% <33.33%> (-0.2%) ⬇️

Comment on lines 135 to 142
q_pos = self.base_distribution.quantile(level)
q_neg = self.base_distribution.quantile(1.0 - level)
cond = F.broadcast_greater(sign, sign.zeros_like())
cond = F.broadcast_add(
cond.expand_dims(axis=1), q_pos.zeros_like()
)
q = F.where(cond, q_pos, q_neg)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes two calls to .quantile instead of one. Wouldn't something like

cond = F.broadcast_greater(sign, sign.zeros_like())
signed_level = F.where(cond, level, 1.0 - level)
q = self.base_distribution.quantile(signed_level)

be more efficient?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what we had before. The problem is that in the current API for .quantile level is supposed to be a 1d tensor of level values, i.e., it doesn't know about the shape of the distribution. The previous code blew up the level to a larger tensor mixing in the shape of sign. It did work (not entirely sure how), but it resulted in very large tensors during the quantile computation that don't fit in GPU memory for e.g. Binned distribution when the distribution dimension was large. Maybe we can rethink the api for quantile to not only support 1d level values, but also level values per distribution dimension.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, thanks for clarifying. If that’s the contract that quantile assumes (scalar or 1D tensor) then I agree that your solution is probably the best.

In a separate story, we may want to start shape assertions in order to avoid these weird situations where things accidentally work :-) (maybe because of some strange broadcasting coincidence)

lostella
lostella previously approved these changes Dec 30, 2019
Copy link
Contributor

@lostella lostella left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@jgasthaus
Copy link
Contributor

Do we have a use case for these bijections with negative Jacobian determinant (i.e. monotonically decreasing)?

@vafl vafl merged commit 4bf7f52 into awslabs:master Jan 2, 2020
@vafl
Copy link
Contributor Author

vafl commented Jan 2, 2020

Good point. Maybe we should just remove the sign stuff and document clearly that we expect positive determinant.

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

Successfully merging this pull request may close these issues.

4 participants