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

Beginning infrastructure for Vecchia GP's #2311

Open
wants to merge 68 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
e954482
First commit for Vecchia module of GPyTorch, implementing a Vecchia-a…
alexpeters1208 Nov 1, 2022
5bca4f9
Update Block to handle 0 neighbors, change names in error messages fr…
alexpeters1208 Nov 1, 2022
ef9eea5
Fix bug in prediction code.
alexpeters1208 Nov 3, 2022
2231706
Update documentation in Block.py.
alexpeters1208 Nov 4, 2022
32e1090
Update more documentation in Block.py.
alexpeters1208 Nov 4, 2022
62472c6
Merge branch 'cornellius-gp:master' into master
alexpeters1208 Nov 8, 2022
8e7d0ec
Begin refactoring of Block class to enable flexible blocking.
alexpeters1208 Nov 11, 2022
b740d0e
Merge branch 'master' of https://github.com/alexpeters1208/gpytorch
alexpeters1208 Nov 11, 2022
9ab69d6
Decouple blocking machinery from k-means implementation with Abstract…
alexpeters1208 Nov 17, 2022
e523b13
Modify KMeansBlocker and mean, covariance function.
alexpeters1208 Nov 17, 2022
ea3be54
Conform AbstractBlocker to PEP.
alexpeters1208 Nov 17, 2022
da67795
Remove blocking and ordering strategies to simplify interface and ali…
alexpeters1208 Nov 23, 2022
6a04718
Merge branch 'cornellius-gp:master' into master
alexpeters1208 Nov 23, 2022
3c01610
Merge branch 'cornellius-gp:master' into master
alexpeters1208 Nov 30, 2022
70d9b33
Add temporary ordering strategies.
alexpeters1208 Dec 15, 2022
b58d3cf
Merge branch 'cornellius-gp:master' into master
alexpeters1208 Jan 9, 2023
a741ff5
Add ordering strategies, modify blocking objects to make use of order…
alexpeters1208 Jan 9, 2023
493ec66
Merge branch 'cornellius-gp:master' into master
alexpeters1208 Jan 17, 2023
23fbf59
Merge remote-tracking branch 'origin/master'
alexpeters1208 Jan 17, 2023
3c37261
Include type hinting in base blocker class.
alexpeters1208 Jan 17, 2023
5bf93fa
Include type hinting in base blocker class.
alexpeters1208 Jan 17, 2023
3b2bddb
Merge branch 'master' of https://github.com/alexpeters1208/gpytorch
alexpeters1208 Jan 17, 2023
4311086
Continue type hinting in BaseBlocker and KMeansBlocker, add documenta…
alexpeters1208 Jan 17, 2023
f94597c
Create plotting method for blocking object.
alexpeters1208 Jan 18, 2023
f1d7edd
Begin example notebook for using blocking object.
alexpeters1208 Jan 19, 2023
faf0900
Continue example notebook for blocking object.
alexpeters1208 Jan 19, 2023
b8cd2e0
Continue example notebook for blocking object.
alexpeters1208 Jan 19, 2023
cf1d7b1
Update KMeansBlocker docstring.
alexpeters1208 Jan 20, 2023
4349c81
Continue tutorial, update docstrings.
alexpeters1208 Jan 20, 2023
771eb83
Continue tutorial, update docstrings.
alexpeters1208 Jan 20, 2023
b71c0b9
Continue tutorial.
alexpeters1208 Jan 20, 2023
9a69346
Continue tutorial.
alexpeters1208 Jan 20, 2023
9b20a56
Modify docstrings, add to tutorial, refactor K-Means blocker to reduc…
alexpeters1208 Jan 31, 2023
ec84472
Continue tutorial.
alexpeters1208 Jan 31, 2023
86880a3
Refactor all blockers and update tutorial.
alexpeters1208 Feb 2, 2023
f688795
Create new approaches to ordering strategies and add parametrized dis…
alexpeters1208 Mar 6, 2023
72341b2
Create new approaches to ordering strategies and add parametrized dis…
alexpeters1208 Mar 6, 2023
7285079
Update tutorial and remove type constraint on distance metrics.
alexpeters1208 Mar 6, 2023
6e91f07
Add first unit test for blocker and refactor blocker.
alexpeters1208 Mar 15, 2023
5e24ac6
Merge latest GPyTorch master into my fork. Crossing my fingers...
alexpeters1208 Mar 15, 2023
07fc664
Update blocker docs.
alexpeters1208 Mar 15, 2023
8f6f912
Merge branch 'cornellius-gp:master' into master
alexpeters1208 Mar 16, 2023
ed7e0a9
Update blocker unit tests.
alexpeters1208 Mar 20, 2023
290e728
Update blocker, add unit testing for K-Means blocker and Vecchia bloc…
alexpeters1208 Mar 23, 2023
f71f38e
Delete files not directly related to blockers for PR.
alexpeters1208 Mar 24, 2023
22fe9f6
Change all names from Blocker to Index.
alexpeters1208 Mar 27, 2023
ce6804c
Delete blocking tutorial.
alexpeters1208 Mar 27, 2023
9b75053
Update Vecchia rst and update names from Blocker to Index.
alexpeters1208 Mar 27, 2023
617c57f
Update docs to eliminate warnings.
alexpeters1208 Mar 27, 2023
3533a97
Update names in Vecchia mean and covariance function.
alexpeters1208 Mar 27, 2023
835baa0
Remove matplotlib dependency and move plotting code into example note…
alexpeters1208 Mar 27, 2023
7ba33fe
Merge branch 'cornellius-gp:master' into blockers
alexpeters1208 May 26, 2023
c51086e
Merge branch 'cornellius-gp:master' into blockers
alexpeters1208 Sep 14, 2023
27e3532
Renaming / moving stuff around from Geoff's suggestions
alexpeters1208 Sep 14, 2023
3bc1ef3
Refactor unit tests with rename
alexpeters1208 Sep 14, 2023
1eee27f
Rename `vecchia` to `nearest_neighbors` in docs
alexpeters1208 Sep 21, 2023
4465b04
Merge branch 'cornellius-gp:master' into blockers
alexpeters1208 Nov 15, 2023
1c349b3
Add FAISS to docs requirements
alexpeters1208 Nov 15, 2023
d58a877
Add FAISS to docs requirements again
alexpeters1208 Nov 15, 2023
1bdebb2
Add FAISS to docs requirements yet again
alexpeters1208 Nov 15, 2023
0c4903e
Trying again
alexpeters1208 Nov 15, 2023
7aa4d7f
Maybe fix build problem?
alexpeters1208 Nov 15, 2023
30cd388
Modify conf.py for build problem, this should not be the case
alexpeters1208 Nov 15, 2023
26d2707
Update examples index
alexpeters1208 Nov 15, 2023
5293230
Update docs labels
alexpeters1208 Nov 15, 2023
f54cdd3
Fix hyperlink
alexpeters1208 Nov 15, 2023
4a5aa2e
Modify notebook
alexpeters1208 Nov 15, 2023
b4f1898
Merge branch 'cornellius-gp:master' into blockers
alexpeters1208 Dec 30, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ def _process(annotation, config):
# For any linear_operator class, the format will be e.g. "~linear_operator.operators.TriangularLinearOperator"
# For any internal class, the format will be e.g. "~gpytorch.kernels.RBFKernel"
elif hasattr(annotation, "__name__"):
module = annotation.__module__ + "."
module = str(annotation.__module__) + "."
if module.split(".")[0] == "linear_operator":
if annotation.__name__.endswith("LinearOperator"):
module = "~linear_operator."
Expand Down
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ GPyTorch's documentation
means
marginal_log_likelihoods
metrics
nearest_neighbors
constraints
distributions
priors
Expand Down
67 changes: 67 additions & 0 deletions docs/source/nearest_neighbors.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
.. role:: hidden
:class: hidden-section

gpytorch.nearest_neighbors
===================================

These modules provide a set of interfaces for partitioning datasets and establishing
neighborhood structures between partitions. This kind of partitioning is required for
nearest-neighbor-style Gaussian Process models, and we ensure behind the scenes that nearest-neighbor models
based on these partitions still form valid joint density functions.

.. automodule:: gpytorch.nearest_neighbors
.. currentmodule:: gpytorch.nearest_neighbors


Indexes
-----------------------------

Indexes are the interfaces used to partition datasets with clustering algorithms, measure distance
between partitions with a distance metric for establishing neighboring structure, and ordering
the data with ordering strategies.

:hidden:`KMeansIndex`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. autoclass:: KMeansIndex
:members:


:hidden:`VoronoiIndex`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. autoclass:: VoronoiIndex
:members:


Distance Metrics
-----------------------------

Distance metrics are used to define distances between partitions of data. Each index defines the
points that represent each block, and distance between blocks is defined as the distance between
these representatives per the supplied distance metric. The DistanceMetrics class includes methods
for Euclidean distance and Manhattan distance metrics, and custom distance metrics must return
functions that take in vectors of observations and return the distance matrix for those observations.

:hidden:`DistanceMetrics`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. autoclass:: DistanceMetrics
:members:


Ordering Strategies
-----------------------------

Because nearest-neighbor approximations depend on the ordering of the data they're trained on, we need a way
to order the dataset by different metrics to find the best ordering strategy for a given problem.
The OrderingStrategies class includes methods for ordering the data by a given coordinate or by an
:math:`L_p` norm. Custom ordering strategies can be implemented here and must return a function that
takes in a vector of observations and returns a vector of integers indicating the index of each observation
under the new ordering.

:hidden:`OrderingStrategies`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. autoclass:: OrderingStrategies
:members:

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions examples/04_Variational_and_Approximate_GPs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Here we provide some examples which highlight some of the common use cases:
- **Variational inference with natural gradient descent** (for faster/better optimization): see the `ngd example`_.
- **Variational inference with contour integral quadrature** (for large numbers of inducing points): see the `ciq example`_.
- **Variational inference with nearest neighbor approximation** (for large numbers of inducing points): see the `vnngp example`_.
- **Customizing nearest-neighbor approximations** for alternative to variational inference: see the `nearest neighbors introduction notebook`_.
- **Variational distribution options** for different scalability/expressiveness: see the `strategy/distribution comparison`_.
- **Alternative optimization objectives** for the GP's predictive distribution: see the `approximate GP objective functions notebook`_.
This example compares and contrasts the variational ELBO with the predictive log likelihood of Jankowiak et al., 2020.
Expand All @@ -46,6 +47,7 @@ Here we provide some examples which highlight some of the common use cases:
PolyaGamma_Binary_Classification.ipynb
SVGP_Multitask_GP_Regression.ipynb
GP_Regression_with_Uncertain_Inputs.ipynb
Getting_Started_with_Nearest_Neighbors.ipynb

.. _strategy/distribution comparison:
./Modifying_the_variational_strategy_and_distribution.ipynb
Expand Down Expand Up @@ -76,3 +78,6 @@ Here we provide some examples which highlight some of the common use cases:

.. _GPs with uncertain inputs example:
./GP_Regression_with_Uncertain_Inputs.ipynb

.. _nearest neighbors introduction notebook:
./Getting_Started_with_Nearest_Neighbors.ipynb
83 changes: 83 additions & 0 deletions gpytorch/nearest_neighbors/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/usr/bin/env python3

from .distance_metrics import *
from .ordering_strategies import *

from ._index import BaseIndex
from .k_means_index import KMeansIndex
from .voronoi_index import VoronoiIndex

__all__ = [
"DistanceMetrics",
"OrderingStrategies",
"BaseIndex",
"KMeansIndex",
"VoronoiIndex",
]


# TODO: Where to put this???
# this function uses an index to compute block mean and covariance for a Vecchia-style GP. Until we have a more
# concrete nearest_neighbors module, I do not know where to put this.
def compute_mean_covar(index, x1, x2, y, mean_module, covar_module, training):

# extract relevant info from index
n_blocks = len(index.blocks)
n_neighbors = len(index.neighbors[-1])

# create empty lists to hold block means and covariances
mean_list = []
cov_list = []

if training:
# append mean function applied to first block in first spot
mean_list.append(mean_module(x1[index.blocks[0]]))
# append within covariance block to first spot
cov_list.append(covar_module(x1[index.blocks[0]], x2[index.blocks[0]]))

if n_neighbors == 0:
# if no neighbors, all index are independent, so simply evaluate mean and covariance for each block
for i in range(1, n_blocks):
mean_list.append(mean_module(x1[index.blocks[i]]))
cov_list.append(covar_module(x1[index.blocks[i]], x2[index.blocks[i]]))

else:
for i in range(1, n_blocks):
# these calculations come from bottom of P7, Quiroz et al, 2021
c_within = covar_module(x1[index.blocks[i]], x2[index.blocks[i]])
c_between = covar_module(x1[index.blocks[i]], x2[index.neighbors[i]])
c_neighbors = covar_module(x1[index.neighbors[i]], x2[index.neighbors[i]])

# use cholesky decomposition to compute inverse, may be numerically unstable with large n_neighbors
l_inv = c_neighbors.cholesky().inverse()
# compute mean
b = c_between @ l_inv.t() @ l_inv
mean = mean_module(x1[index.blocks[i]]) + b @ (
y[index.neighbors[i]] - mean_module(x2[index.neighbors[i]])
)
# compute covariance
f = c_within - (c_between @ l_inv.t() @ l_inv @ c_between.t())

mean_list.append(mean)
cov_list.append(f)

else:
for i in range(0, len(index.blocks)):
c_within = covar_module(x1[index.test_blocks[i]], x1[index.test_blocks[i]])
c_between = covar_module(x1[index.test_blocks[i]], x2[index.test_neighbors[i]])
c_neighbors = covar_module(x2[index.test_neighbors[i]], x2[index.test_neighbors[i]])

# use cholesky decomposition to compute needed terms, may be numerically unstable with large n_neighbors
l_inv = c_neighbors.cholesky().inverse()
# compute mean
b = c_between @ l_inv.t() @ l_inv
mean = mean_module(x1[index.test_blocks[i]]) + b @ (
y[index.test_neighbors[i]] - mean_module(x2[index.test_neighbors[i]])
)
# compute covariance
f = c_within - (c_between @ l_inv.t() @ l_inv @ c_between.t())

mean_list.append(mean)
cov_list.append(f)

return mean_list, cov_list
Loading