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
Fixed broadcasting rules for gpflow.models.model.predict_y, partially resolves #1461. #1597
base: develop
Are you sure you want to change the base?
Conversation
I've opened this PR a bit early, as I'd like review of the design choices made. I will be adding unit tests once we're happy with code quality/design decisions before closing the PR. With regards to automatic style rules enforced by black/isort, I found that many drastic changes are recommended for these well trafficked files, would we like to make these drastic changes recommended by black/isort? Thanks, Mohit |
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.
Hi, many thanks for your PR! I've left you an initial set of comments that will help me better understand what problem you are trying to solve. Happy to iterate over this.
return self.likelihood.predict_mean_and_var(f_mean, f_var) | ||
|
||
if full_cov and full_output_cov: | ||
f_var_mat = tf.reshape(f_var, [1, f_var.shape[0]*f_var.shape[1], f_var.shape[2]*f_var.shape[3]]) |
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.
Would be nice if you could add expected shapes of tensors at the end of the line, for example
f_mean, f_var = ... # [N, P, N, P] or [N, P, P], etc.
return self.likelihood.predict_mean_and_var(f_mean, f_var) | ||
|
||
if full_cov and full_output_cov: | ||
f_var_mat = tf.reshape(f_var, [1, f_var.shape[0]*f_var.shape[1], f_var.shape[2]*f_var.shape[3]]) |
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 probably want to use tf.shape(tensor)
instead of tensor.shape
, the former will work in both compiled and eager mode, while the latter only works in eager mode.
if full_cov and full_output_cov: | ||
f_var_mat = tf.reshape(f_var, [1, f_var.shape[0]*f_var.shape[1], f_var.shape[2]*f_var.shape[3]]) | ||
f_mean_pred, f_var_pred = self.likelihood.predict_mean_and_var(f_mean, f_var_mat) | ||
return f_mean_pred, tf.reshape(f_var_pred, f_var.shape) |
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.
Shape comments would be helpful here as well.
return tf.identity(Fmu), Fvar + self.variance | ||
rank = tf.rank(Fvar).numpy() | ||
if rank == 2: | ||
return tf.identity(Fmu), Fvar + self.variance |
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.
I know this is not related to your PR, but I think we can drop the tf.identity
s here, as this is a no-op and looks like legacy code.
rank = tf.rank(Fvar).numpy() | ||
if rank == 2: | ||
return tf.identity(Fmu), Fvar + self.variance | ||
else: |
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 we, please, have an elif
that matches the exact ranks you want to target here, and another else
that raises a NotImplementedError
for the ones we do not support?
PR type: new feature
**Related issue(s)/PRs:#1461
Summary
Proposed changes
This proposed change fixes the broadcasting rules for predict_y to correctly handle full_cov/full_output_cov = True. The changes made rely on slightly abusing tf broadcasting rules in a compatible manner to the covariance matrix/tensor when full_cov/full_output_cov = True.
What alternatives have you considered?
I think at this time we should keep predict_log_densities for full_cov/full_output_cov = True as is. The reasoning behind this is that with large covariance matrix/tensors, there is no efficient way to compute these exactly without hitting OOM issues. I strongly prefer keeping the predict_log_densities 'as-is' to avoid a situation where predict_log_densities takes far too long to run, or approximates a solution.
Minimal working example
PR checklist
make format
)make check-all
)Release notes
Fully backwards compatible: yes
If not, why is it worth breaking backwards compatibility:
Commit message (for release notes): Fixed broadcasting rules for gpflow.models.model.predict_y, partially resolves #1461.