-
Notifications
You must be signed in to change notification settings - Fork 22
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
Clarify API for GP approximations #361
Conversation
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## master #361 +/- ##
==========================================
- Coverage 97.63% 96.89% -0.74%
==========================================
Files 10 10
Lines 380 387 +7
==========================================
+ Hits 371 375 +4
- Misses 9 12 +3
☔ View full report in Codecov by Sentry. |
Should there be an |
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Hm... where would that be useful? Is there anything that you would be able to do with any approximation, without knowing what approximation it is (i.e. it'd be necessary as a common base type in the hierarchy)? Or just as a "type hint" (i.e. it might be better to just improve the docs)? |
Open question from #221 (comment): should we add a |
I think this makes sense to me, with appropriate aliases for the current two argument form. Re the above, I was thinking about a type hint, need to think about whether such a type might also be useful elsewhere. |
One way I can think of where a |
…tractGPs.jl into st/3posterior
src/exact_gpr_posterior.jl
Outdated
@@ -3,6 +3,12 @@ struct PosteriorGP{Tprior,Tdata} <: AbstractGP | |||
data::Tdata | |||
end | |||
|
|||
struct ExactGP end | |||
|
|||
posterior(::ExactGP, fx::FiniteGP, y::AbstractVector{<:Real}) = posterior(fx, y) |
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 would have gone the other way around?
But maybe that's too complicated...
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 find this order of arguments quite intuitive.
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.
Sorry I meant that the implemented definition would be posterior(::ExactPosterior, gp, y) and that posterior(gp, y) would default to it.
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.
Does it make any difference in practice? (I kinda like it as it is but that might just be status-quo bias too...)
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.
In practice I think the answer is no.
Within the code, there might be something to be said for consistency. Every posterior
is defined with the 3-argument form, but the exact one gets a special alias.
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.
To be fair, there is only one posterior. Shouldn't VFE and DTC dispatched on approx_posterior?
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.
@theogf what do you mean? there is no approx_posterior
method..
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.
haha somehow in my mind there was a approx_posterior
method. So yeah then it's back to
- Should we have a unique 3-args posterior API (where the 2-args default to
ExactInference
) ? - Should we just have 2-args methods and have the GP wrapped (like in ApproximateGPs) ?
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.
ApproximateGPs has the 3-args posterior though, no wrapping?
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
""" | ||
DTC(fz::FiniteGP) | ||
|
||
Similar to `VFE`, but uses a different objective for `approx_log_evidence`. |
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.
Could maybe do with a better docstring but then it needs to be sorted out more thoroughly anyways (see #309) and I can't think of what it should be right now, so would leave that for some other PR/person/time...
@testset "approx_log_evidence" begin | ||
x = collect(Float64, range(-1.0, 1.0; length=N_cond)) | ||
f = GP(SqExponentialKernel()) | ||
fx = f(x, 0.1) | ||
y = rand(rng, fx) | ||
|
||
# Ensure that the elbo/dtc objective is close to the logpdf when appropriate. | ||
@test approx_log_evidence(ApproxType(f(x)), fx, y) isa Real | ||
@test approx_log_evidence(ApproxType(f(x)), fx, y) ≈ logpdf(fx, y) | ||
|
||
if ApproxType === VFE | ||
@test elbo(ApproxType(f(x)), fx, y) == | ||
approx_log_evidence(ApproxType(f(x)), fx, y) | ||
@test elbo(ApproxType(f(x .+ randn(rng, N_cond))), fx, y) < logpdf(fx, y) | ||
end | ||
end |
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.
this is the main change
Hello! What do you think needs doing/addressing/... before merging this ? |
_update_approx(f_post_approx.approx, fz_new), f_post_approx.prior, cache | ||
) | ||
end | ||
|
||
_update_approx(vfe::VFE, fz_new::FiniteGP) = VFE(fz_new) | ||
_update_approx(dtc::DTC, fz_new::FiniteGP) = DTC(fz_new) |
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.
is this the right way to handle this? if anyone can think of a better approach please say:)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Summary
AbstractGPs.jl should define the API we expect across the ecosystem. Currently, this is not the case for GP approximations, even though they're already introduced in this package (
VFE
for sparse GPR).Proposed changes
Expose
posterior
andapprox_log_evidence
as part of the API with nice generic docstrings explaining their purpose.Related issues
Resolves #221
Also see #223, #241, #318, maybe #319
What alternatives have you considered?
Status quo: some definitions in ApproximateGPs.jl, but people not realizing that you could just use a three-parameter form for
posterior
, leading to more reimplementation of base FiniteGPs than would be necessary (e.g. https://github.com/SebastianCallh/IterGP.jl/blob/AbstractGPs-interface/src/gp.jl)