fvgp 4.2.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fvgp/.editorconfig +21 -0
- fvgp/.github/ISSUE_TEMPLATE.md +15 -0
- fvgp/.gitignore +105 -0
- fvgp/.travis.yml +14 -0
- fvgp/__init__.py +20 -0
- fvgp/_version.py +16 -0
- fvgp/deep_kernel_network.py +35 -0
- fvgp/fvgp.py +413 -0
- fvgp/gp.py +1339 -0
- fvgp/gpMCMC.py +319 -0
- fvgp/gp_data.py +66 -0
- fvgp/gp_kernels.py +488 -0
- fvgp/gp_likelihood.py +123 -0
- fvgp/gp_lin_alg.py +269 -0
- fvgp/gp_marginal_density.py +361 -0
- fvgp/gp_posterior.py +467 -0
- fvgp/gp_prior.py +397 -0
- fvgp/gp_training.py +389 -0
- fvgp/mcmc.py +176 -0
- fvgp-4.2.10.dist-info/METADATA +105 -0
- fvgp-4.2.10.dist-info/RECORD +25 -0
- fvgp-4.2.10.dist-info/WHEEL +4 -0
- fvgp-4.2.10.dist-info/licenses/AUTHORS.rst +13 -0
- fvgp-4.2.10.dist-info/licenses/COPYING +674 -0
- fvgp-4.2.10.dist-info/licenses/LICENSE +31 -0
fvgp/.editorconfig
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# http://editorconfig.org
|
|
2
|
+
|
|
3
|
+
root = true
|
|
4
|
+
|
|
5
|
+
[*]
|
|
6
|
+
indent_style = space
|
|
7
|
+
indent_size = 4
|
|
8
|
+
trim_trailing_whitespace = true
|
|
9
|
+
insert_final_newline = true
|
|
10
|
+
charset = utf-8
|
|
11
|
+
end_of_line = lf
|
|
12
|
+
|
|
13
|
+
[*.bat]
|
|
14
|
+
indent_style = tab
|
|
15
|
+
end_of_line = crlf
|
|
16
|
+
|
|
17
|
+
[LICENSE]
|
|
18
|
+
insert_final_newline = false
|
|
19
|
+
|
|
20
|
+
[Makefile]
|
|
21
|
+
indent_style = tab
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
* fvGP version:
|
|
2
|
+
* Python version:
|
|
3
|
+
* Operating System:
|
|
4
|
+
|
|
5
|
+
### Description
|
|
6
|
+
|
|
7
|
+
Describe what you were trying to get done.
|
|
8
|
+
Tell us what happened, what went wrong, and what you expected to happen.
|
|
9
|
+
|
|
10
|
+
### What I Did
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
Paste the command(s) you ran and the output.
|
|
14
|
+
If there was a crash, please include the traceback here.
|
|
15
|
+
```
|
fvgp/.gitignore
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
env/
|
|
12
|
+
build/
|
|
13
|
+
develop-eggs/
|
|
14
|
+
dist/
|
|
15
|
+
downloads/
|
|
16
|
+
eggs/
|
|
17
|
+
.eggs/
|
|
18
|
+
lib/
|
|
19
|
+
lib64/
|
|
20
|
+
parts/
|
|
21
|
+
sdist/
|
|
22
|
+
var/
|
|
23
|
+
wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
|
|
28
|
+
# PyInstaller
|
|
29
|
+
# Usually these files are written by a python script from a template
|
|
30
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
31
|
+
*.manifest
|
|
32
|
+
*.spec
|
|
33
|
+
|
|
34
|
+
# Installer logs
|
|
35
|
+
pip-log.txt
|
|
36
|
+
pip-delete-this-directory.txt
|
|
37
|
+
|
|
38
|
+
# Unit test / coverage reports
|
|
39
|
+
htmlcov/
|
|
40
|
+
.tox/
|
|
41
|
+
.coverage
|
|
42
|
+
.coverage.*
|
|
43
|
+
.cache
|
|
44
|
+
nosetests.xml
|
|
45
|
+
coverage.xml
|
|
46
|
+
*.cover
|
|
47
|
+
.hypothesis/
|
|
48
|
+
.pytest_cache/
|
|
49
|
+
|
|
50
|
+
# Translations
|
|
51
|
+
*.mo
|
|
52
|
+
*.pot
|
|
53
|
+
|
|
54
|
+
# Django stuff:
|
|
55
|
+
*.log
|
|
56
|
+
local_settings.py
|
|
57
|
+
|
|
58
|
+
# Flask stuff:
|
|
59
|
+
instance/
|
|
60
|
+
.webassets-cache
|
|
61
|
+
|
|
62
|
+
# Scrapy stuff:
|
|
63
|
+
.scrapy
|
|
64
|
+
|
|
65
|
+
# Sphinx documentation
|
|
66
|
+
docs/_build/
|
|
67
|
+
|
|
68
|
+
# PyBuilder
|
|
69
|
+
target/
|
|
70
|
+
|
|
71
|
+
# Jupyter Notebook
|
|
72
|
+
.ipynb_checkpoints
|
|
73
|
+
|
|
74
|
+
# pyenv
|
|
75
|
+
.python-version
|
|
76
|
+
|
|
77
|
+
# celery beat schedule file
|
|
78
|
+
celerybeat-schedule
|
|
79
|
+
|
|
80
|
+
# SageMath parsed files
|
|
81
|
+
*.sage.py
|
|
82
|
+
|
|
83
|
+
# dotenv
|
|
84
|
+
.env
|
|
85
|
+
|
|
86
|
+
# virtualenv
|
|
87
|
+
.venv
|
|
88
|
+
venv/
|
|
89
|
+
ENV/
|
|
90
|
+
|
|
91
|
+
# Spyder project settings
|
|
92
|
+
.spyderproject
|
|
93
|
+
.spyproject
|
|
94
|
+
|
|
95
|
+
# Rope project settings
|
|
96
|
+
.ropeproject
|
|
97
|
+
|
|
98
|
+
# mkdocs documentation
|
|
99
|
+
/site
|
|
100
|
+
|
|
101
|
+
# mypy
|
|
102
|
+
.mypy_cache/
|
|
103
|
+
|
|
104
|
+
# IDE settings
|
|
105
|
+
.vscode/
|
fvgp/.travis.yml
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Config file for automatic testing at travis-ci.com
|
|
2
|
+
|
|
3
|
+
language: python
|
|
4
|
+
python:
|
|
5
|
+
- 3.10
|
|
6
|
+
- 3.9
|
|
7
|
+
|
|
8
|
+
# Command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors
|
|
9
|
+
install: pip install -U tox-travis
|
|
10
|
+
|
|
11
|
+
# Command to run tests, e.g. python setup.py test
|
|
12
|
+
script: tox
|
|
13
|
+
|
|
14
|
+
|
fvgp/__init__.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Top-level package for fvGP."""
|
|
2
|
+
|
|
3
|
+
__author__ = """Marcus Michael Noack"""
|
|
4
|
+
__email__ = 'MarcusNoack@lbl.gov'
|
|
5
|
+
|
|
6
|
+
try:
|
|
7
|
+
from ._version import __version__
|
|
8
|
+
except (ImportError, ModuleNotFoundError) as ex:
|
|
9
|
+
raise RuntimeError('Running fvgp from source code requires installation. If you would like an editable source '
|
|
10
|
+
'install, use "pip install -e ." to perform and editable installation.') from ex
|
|
11
|
+
|
|
12
|
+
from loguru import logger
|
|
13
|
+
import sys
|
|
14
|
+
from .gp import GP
|
|
15
|
+
from .fvgp import fvGP
|
|
16
|
+
from .gpMCMC import gpMCMC
|
|
17
|
+
|
|
18
|
+
__all__ = ['GP', 'fvGP']
|
|
19
|
+
|
|
20
|
+
logger.disable('fvgp')
|
fvgp/_version.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# file generated by setuptools_scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
TYPE_CHECKING = False
|
|
4
|
+
if TYPE_CHECKING:
|
|
5
|
+
from typing import Tuple, Union
|
|
6
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
7
|
+
else:
|
|
8
|
+
VERSION_TUPLE = object
|
|
9
|
+
|
|
10
|
+
version: str
|
|
11
|
+
__version__: str
|
|
12
|
+
__version_tuple__: VERSION_TUPLE
|
|
13
|
+
version_tuple: VERSION_TUPLE
|
|
14
|
+
|
|
15
|
+
__version__ = version = '4.2.10'
|
|
16
|
+
__version_tuple__ = version_tuple = (4, 2, 10)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
from torch import nn
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Network(nn.Module): # pragma: no cover
|
|
6
|
+
def __init__(self, dim, layer_width):
|
|
7
|
+
super().__init__()
|
|
8
|
+
# Inputs to hidden layer linear transformation
|
|
9
|
+
self.layer1 = nn.Linear(dim, layer_width)
|
|
10
|
+
self.layer2 = nn.Linear(layer_width, layer_width)
|
|
11
|
+
self.layer3 = nn.Linear(layer_width, dim)
|
|
12
|
+
self.number_of_hps = int(2. * dim * layer_width + layer_width ** 2 + 2. * layer_width + dim)
|
|
13
|
+
|
|
14
|
+
def forward(self, x):
|
|
15
|
+
x = torch.Tensor(x)
|
|
16
|
+
x = torch.nn.functional.relu(self.layer1(x))
|
|
17
|
+
x = torch.nn.functional.relu(self.layer2(x))
|
|
18
|
+
x = torch.nn.functional.relu(self.layer3(x))
|
|
19
|
+
return x.detach().numpy()
|
|
20
|
+
|
|
21
|
+
def set_weights(self, w1, w2, w3):
|
|
22
|
+
with torch.no_grad(): self.layer1.weight = nn.Parameter(torch.from_numpy(w1).float())
|
|
23
|
+
with torch.no_grad(): self.layer2.weight = nn.Parameter(torch.from_numpy(w2).float())
|
|
24
|
+
with torch.no_grad(): self.layer3.weight = nn.Parameter(torch.from_numpy(w3).float())
|
|
25
|
+
|
|
26
|
+
def set_biases(self, b1, b2, b3):
|
|
27
|
+
with torch.no_grad(): self.layer1.bias = nn.Parameter(torch.from_numpy(b1).float())
|
|
28
|
+
with torch.no_grad(): self.layer2.bias = nn.Parameter(torch.from_numpy(b2).float())
|
|
29
|
+
with torch.no_grad(): self.layer3.bias = nn.Parameter(torch.from_numpy(b3).float())
|
|
30
|
+
|
|
31
|
+
def get_weights(self):
|
|
32
|
+
return self.layer1.weight, self.layer2.weight, self.layer3.weight
|
|
33
|
+
|
|
34
|
+
def get_biases(self):
|
|
35
|
+
return self.layer1.bias, self.layer2.bias, self.layer3.bias
|
fvgp/fvgp.py
ADDED
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
import numpy as np
|
|
3
|
+
from .gp import GP
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class fvGP(GP):
|
|
7
|
+
"""
|
|
8
|
+
This class provides all the tools for a multi-task Gaussian Process (GP).
|
|
9
|
+
This class allows for full HPC support for training. After initialization, this
|
|
10
|
+
class provides all the methods described for the GP class.
|
|
11
|
+
|
|
12
|
+
V ... number of input points
|
|
13
|
+
|
|
14
|
+
Di... input space dimensionality
|
|
15
|
+
|
|
16
|
+
Do... output space dimensionality
|
|
17
|
+
|
|
18
|
+
No... number of outputs
|
|
19
|
+
|
|
20
|
+
N ... arbitrary integers (N1, N2,...)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
The main logic of fvGP is that any multi-task GP is just a single-task GP
|
|
24
|
+
over a Cartesian product space of input and output space, as long as the kernel
|
|
25
|
+
is flexible enough, so prepare to work on your kernel. This is the best
|
|
26
|
+
way to give the user optimal control and power. In the
|
|
27
|
+
prior-mean function, noise function, and kernel function definition, you will
|
|
28
|
+
see that the input `x` is defined over this combined space.
|
|
29
|
+
For example, if your input space is a Euclidean 2d space and your output
|
|
30
|
+
is labelled [0,1], the input to the mean, kernel, and noise function might be
|
|
31
|
+
|
|
32
|
+
x =
|
|
33
|
+
|
|
34
|
+
[[0.2, 0.3,0],[0.9,0.6,0],
|
|
35
|
+
|
|
36
|
+
[0.2, 0.3,1],[0.9,0.6,1]]
|
|
37
|
+
|
|
38
|
+
This has to be understood and taken into account when customizing fvGP for multi-task
|
|
39
|
+
use. The examples will provide deeper insight.
|
|
40
|
+
|
|
41
|
+
Parameters
|
|
42
|
+
----------
|
|
43
|
+
x_data : np.ndarray
|
|
44
|
+
The input point positions. Shape (V x D), where D is the `input_space_dim`.
|
|
45
|
+
y_data : np.ndarray
|
|
46
|
+
The values of the data points. Shape (V,No).
|
|
47
|
+
init_hyperparameters : np.ndarray, optional
|
|
48
|
+
Vector of hyperparameters used by the GP initially.
|
|
49
|
+
This class provides methods to train hyperparameters.
|
|
50
|
+
The default is an array that specifies the right number of
|
|
51
|
+
initial hyperparameters for the default kernel, which is
|
|
52
|
+
a deep kernel with two layers of width
|
|
53
|
+
fvgp.fvGP.gp_deep_kernel_layer_width. If you specify
|
|
54
|
+
another kernel, please provide
|
|
55
|
+
init_hyperparameters.
|
|
56
|
+
output_positions : np.ndarray, optional
|
|
57
|
+
A 2-D numpy array of shape (U x output_number), so that for each measurement position, the outputs
|
|
58
|
+
are clearly defined by their positions in the output space. The default is
|
|
59
|
+
np.array([[0,1,2,3,...,output_number - 1],[0,1,2,3,...,output_number - 1],...]).
|
|
60
|
+
noise_variances : np.ndarray, optional
|
|
61
|
+
An numpy array defining the uncertainties/noise in the data
|
|
62
|
+
`y_data` in form of a point-wise variance. Shape y_data.shape.
|
|
63
|
+
Note: if no noise_variances are provided here, the gp_noise_function
|
|
64
|
+
callable will be used; if the callable is not provided, the noise variances
|
|
65
|
+
will be set to `abs(np.mean(y_data) / 100.0`. If
|
|
66
|
+
noise covariances are required, also make use of the gp_noise_function.
|
|
67
|
+
compute_device : str, optional
|
|
68
|
+
One of "cpu" or "gpu", determines how linear system solves are run. The default is "cpu".
|
|
69
|
+
For "gpu", pytorch has to be installed manually.
|
|
70
|
+
If gp2Scale is enabled but no kernel is provided, the choice of the compute_device
|
|
71
|
+
becomes much more important. In that case, the default kernel will be computed on
|
|
72
|
+
the cpu or the gpu which will significantly change the compute time depending on the compute
|
|
73
|
+
architecture.
|
|
74
|
+
gp_kernel_function : Callable, optional
|
|
75
|
+
A symmetric positive semi-definite covariance function (a kernel)
|
|
76
|
+
that calculates the covariance between
|
|
77
|
+
data points. It is a function of the form k(x1,x2,hyperparameters, obj).
|
|
78
|
+
The input x1 is a N1 x Di+Do array of positions, x2 is a N2 x Di+Do
|
|
79
|
+
array of positions, the hyperparameters argument
|
|
80
|
+
is a 1d array of length N depending on how many hyperparameters are initialized, and
|
|
81
|
+
obj is an `fvgp.GP` instance. The default is a deep kernel with 2 hidden layers and
|
|
82
|
+
a width of fvgp.fvGP.gp_deep_kernel_layer_width.
|
|
83
|
+
gp_kernel_function_grad : Callable, optional
|
|
84
|
+
A function that calculates the derivative of the `gp_kernel_function` with respect to the hyperparameters.
|
|
85
|
+
If provided, it will be used for local training (optimization) and can speed up the calculations.
|
|
86
|
+
It accepts as input x1 (a N1 x Di+Do array of positions),
|
|
87
|
+
x2 (a N2 x Di+Do array of positions),
|
|
88
|
+
hyperparameters, and a
|
|
89
|
+
`fvgp.GP` instance. The default is a finite difference calculation.
|
|
90
|
+
If 'ram_economy' is True, the function's input is x1, x2, direction (int), hyperparameters (numpy array), and a
|
|
91
|
+
`fvgp.GP` instance, and the output
|
|
92
|
+
is a numpy array of shape (len(hps) x N).
|
|
93
|
+
If 'ram economy' is False,the function's input is x1, x2, hyperparameters, and a
|
|
94
|
+
`fvgp.GP` instance. The output is
|
|
95
|
+
a numpy array of shape (len(hyperparameters) x N1 x N2). See 'ram_economy'.
|
|
96
|
+
gp_mean_function : Callable, optional
|
|
97
|
+
A function that evaluates the prior mean at a set of input position. It accepts as input
|
|
98
|
+
an array of positions (of shape N1 x Di+Do), hyperparameters
|
|
99
|
+
and a `fvgp.GP` instance. The return value is a 1d array of length N1. If None is provided,
|
|
100
|
+
`fvgp.GP._default_mean_function` is used.
|
|
101
|
+
gp_mean_function_grad : Callable, optional
|
|
102
|
+
A function that evaluates the gradient of the ``gp_mean_function'' at a set of input positions with respect to
|
|
103
|
+
the hyperparameters. It accepts as input an array of positions (of size N1 x Di+Do), hyperparameters
|
|
104
|
+
and a `fvgp.GP` instance. The return value is a 2d array of shape (len(hyperparameters) x N1). If None is
|
|
105
|
+
provided, either zeros are returned since the default mean function does not depend on hyperparameters, or a
|
|
106
|
+
finite-difference approximation is used if ``gp_mean_function'' is provided.
|
|
107
|
+
gp_noise_function : Callable optional
|
|
108
|
+
The noise function is a callable f(x,hyperparameters,obj) that returns a
|
|
109
|
+
positive symmetric definite matrix of shape(len(x),len(x)).
|
|
110
|
+
The input x is a numpy array of shape (N x Di+Do). The hyperparameter array is the same
|
|
111
|
+
that is communicated to mean and kernel functions. The obj is a fvgp.fvGP instance.
|
|
112
|
+
gp_noise_function_grad : Callable, optional
|
|
113
|
+
A function that evaluates the gradient of the ``gp_noise_function'' at an input position with respect
|
|
114
|
+
to the hyperparameters. It accepts as input an array of positions (of size N x Di+Do),
|
|
115
|
+
hyperparameters (a 1d array of length D+1 for the default kernel)
|
|
116
|
+
and a `fvgp.GP` instance. The return value is a 3-D array of shape
|
|
117
|
+
(len(hyperparameters) x N x N). If None is provided, either
|
|
118
|
+
zeros are returned since the default noise function does not depend on hyperparameters.
|
|
119
|
+
If ``gp_noise_function'' is provided but no gradient function,
|
|
120
|
+
a finite-difference approximation will be used.
|
|
121
|
+
The same rules regarding ram economy as for the kernel definition apply here.
|
|
122
|
+
gp2Scale: bool, optional
|
|
123
|
+
Turns on gp2Scale. This will distribute the covariance computations across multiple workers.
|
|
124
|
+
This is an advanced feature for HPC GPs up to 10
|
|
125
|
+
million datapoints. If gp2Scale is used, the default kernel is an anisotropic Wendland
|
|
126
|
+
kernel which is compactly supported. The noise function will have
|
|
127
|
+
to return a scipy.sparse matrix instead of a numpy array. There are a few more things
|
|
128
|
+
to consider (read on); this is an advanced option.
|
|
129
|
+
If no kernel is provided, the compute_device option should be revisited. The kernel will
|
|
130
|
+
use the specified device to compute covariances.
|
|
131
|
+
The default is False.
|
|
132
|
+
gp2Scale_dask_client : dask.distributed.Client, optional
|
|
133
|
+
A dask client for gp2Scale to distribute covariance computations over. Has to contain at least 3 workers.
|
|
134
|
+
On HPC architecture, this client is provided by the jobscript. Please have a look at the examples.
|
|
135
|
+
A local client is used as default.
|
|
136
|
+
gp2Scale_batch_size : int, optional
|
|
137
|
+
Matrix batch size for distributed computing in gp2Scale. The default is 10000.
|
|
138
|
+
calc_inv : bool, optional
|
|
139
|
+
If True, the algorithm calculates and stores the inverse of the covariance
|
|
140
|
+
matrix after each training or update of the dataset or hyperparameters,
|
|
141
|
+
which makes computing the posterior covariance faster (5-10 times).
|
|
142
|
+
For larger problems (>2000 data points), the use of inversion should be avoided due
|
|
143
|
+
to computational instability and costs. The default is
|
|
144
|
+
False. Note, the training will always use Cholesky or LU decomposition instead of the
|
|
145
|
+
inverse for stability reasons. Storing the inverse is
|
|
146
|
+
a good option when the dataset is not too large and the posterior covariance is heavily used.
|
|
147
|
+
ram_economy : bool, optional
|
|
148
|
+
Only of interest if the gradient and/or Hessian of the marginal log_likelihood
|
|
149
|
+
is/are used for the training.
|
|
150
|
+
If True, components of the derivative of the marginal log-likelihood are calculated
|
|
151
|
+
subsequently, leading to a slow-down
|
|
152
|
+
but much less RAM usage. If the derivative of the kernel (or noise function) with
|
|
153
|
+
respect to the hyperparameters (gp_kernel_function_grad) is
|
|
154
|
+
going to be provided, it has to be tailored: for ram_economy=True it should be of
|
|
155
|
+
the form f(x1[, x2], direction, hyperparameters, obj)
|
|
156
|
+
and return a 2d numpy array of shape len(x1) x len(x2).
|
|
157
|
+
If ram_economy=False, the function should be of the form f(x1[, x2,] hyperparameters, obj)
|
|
158
|
+
and return a numpy array of shape
|
|
159
|
+
H x len(x1) x len(x2), where H is the number of hyperparameters. CAUTION:
|
|
160
|
+
This array will be stored and is very large.
|
|
161
|
+
args : any, optional
|
|
162
|
+
args will be a class attribute and therefore available to kernel, noise and prior mean functions.
|
|
163
|
+
info : bool, optional
|
|
164
|
+
Provides a way how to see the progress of gp2Scale, Default is False
|
|
165
|
+
|
|
166
|
+
Attributes
|
|
167
|
+
----------
|
|
168
|
+
x_data : np.ndarray
|
|
169
|
+
Datapoint positions
|
|
170
|
+
y_data : np.ndarray
|
|
171
|
+
Datapoint values
|
|
172
|
+
fvgp_x_data : np.ndarray
|
|
173
|
+
Datapoint positions as seen by fvgp
|
|
174
|
+
fvgp_y_data : np.ndarray
|
|
175
|
+
Datapoint values as seen by fvgp
|
|
176
|
+
noise_variances : np.ndarray
|
|
177
|
+
Datapoint observation (co)variances.
|
|
178
|
+
prior.hyperparameters : np.ndarray
|
|
179
|
+
Current hyperparameters in use.
|
|
180
|
+
prior.K : np.ndarray
|
|
181
|
+
Current prior covariance matrix of the GP
|
|
182
|
+
prior.m : np.ndarray
|
|
183
|
+
Current prior mean vector.
|
|
184
|
+
marginal_density.KVinv : np.ndarray
|
|
185
|
+
If enabled, the inverse of the prior covariance + nose matrix V
|
|
186
|
+
inv(K+V)
|
|
187
|
+
marginal_density.KVlogdet : float
|
|
188
|
+
logdet(K+V)
|
|
189
|
+
likelihood.V : np.ndarray
|
|
190
|
+
the noise covariance matrix
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
This class inherits all capabilities from :py:class:`fvgp.GP`.
|
|
194
|
+
Check there for a full list of capabilities. Here are the most important.
|
|
195
|
+
|
|
196
|
+
Base-GP Methods:
|
|
197
|
+
|
|
198
|
+
:py:meth:`fvgp.GP.train`
|
|
199
|
+
|
|
200
|
+
:py:meth:`fvgp.GP.train_async`
|
|
201
|
+
|
|
202
|
+
:py:meth:`fvgp.GP.stop_training`
|
|
203
|
+
|
|
204
|
+
:py:meth:`fvgp.GP.kill_training`
|
|
205
|
+
|
|
206
|
+
:py:meth:`fvgp.GP.update_hyperparameters`
|
|
207
|
+
|
|
208
|
+
:py:meth:`fvgp.GP.set_hyperparameters`
|
|
209
|
+
|
|
210
|
+
:py:meth:`fvgp.GP.get_hyperparameters`
|
|
211
|
+
|
|
212
|
+
Posterior Evaluations:
|
|
213
|
+
|
|
214
|
+
:py:meth:`fvgp.GP.posterior_mean`
|
|
215
|
+
|
|
216
|
+
:py:meth:`fvgp.GP.posterior_covariance`
|
|
217
|
+
|
|
218
|
+
:py:meth:`fvgp.GP.posterior_mean_grad`
|
|
219
|
+
|
|
220
|
+
:py:meth:`fvgp.GP.posterior_covariance_grad`
|
|
221
|
+
|
|
222
|
+
:py:meth:`fvgp.GP.joint_gp_prior`
|
|
223
|
+
|
|
224
|
+
:py:meth:`fvgp.GP.joint_gp_prior_grad`
|
|
225
|
+
|
|
226
|
+
:py:meth:`fvgp.GP.gp_entropy`
|
|
227
|
+
|
|
228
|
+
:py:meth:`fvgp.GP.gp_entropy_grad`
|
|
229
|
+
|
|
230
|
+
:py:meth:`fvgp.GP.gp_kl_div`
|
|
231
|
+
|
|
232
|
+
:py:meth:`fvgp.GP.gp_kl_div_grad`
|
|
233
|
+
|
|
234
|
+
:py:meth:`fvgp.GP.gp_mutual_information`
|
|
235
|
+
|
|
236
|
+
:py:meth:`fvgp.GP.gp_total_correlation`
|
|
237
|
+
|
|
238
|
+
:py:meth:`fvgp.GP.gp_relative_information_entropy`
|
|
239
|
+
|
|
240
|
+
:py:meth:`fvgp.GP.gp_relative_information_entropy_set`
|
|
241
|
+
|
|
242
|
+
:py:meth:`fvgp.GP.posterior_probability`
|
|
243
|
+
|
|
244
|
+
:py:meth:`fvgp.GP.posterior_probability_grad`
|
|
245
|
+
|
|
246
|
+
Validation Methods:
|
|
247
|
+
|
|
248
|
+
:py:meth:`fvgp.GP.crps`
|
|
249
|
+
|
|
250
|
+
:py:meth:`fvgp.GP.rmse`
|
|
251
|
+
|
|
252
|
+
:py:meth:`fvgp.GP.make_2d_x_pred`
|
|
253
|
+
|
|
254
|
+
:py:meth:`fvgp.GP.make_1d_x_pred`
|
|
255
|
+
|
|
256
|
+
:py:meth:`fvgp.GP.log_likelihood`
|
|
257
|
+
|
|
258
|
+
:py:meth:`fvgp.GP.test_log_likelihood_gradient`
|
|
259
|
+
"""
|
|
260
|
+
|
|
261
|
+
def __init__(
|
|
262
|
+
self,
|
|
263
|
+
x_data,
|
|
264
|
+
y_data,
|
|
265
|
+
init_hyperparameters=None,
|
|
266
|
+
output_positions=None,
|
|
267
|
+
noise_variances=None,
|
|
268
|
+
compute_device="cpu",
|
|
269
|
+
gp_kernel_function=None,
|
|
270
|
+
gp_kernel_function_grad=None,
|
|
271
|
+
gp_noise_function=None,
|
|
272
|
+
gp_noise_function_grad=None,
|
|
273
|
+
gp_mean_function=None,
|
|
274
|
+
gp_mean_function_grad=None,
|
|
275
|
+
gp2Scale=False,
|
|
276
|
+
gp2Scale_dask_client=None,
|
|
277
|
+
gp2Scale_batch_size=10000,
|
|
278
|
+
calc_inv=False,
|
|
279
|
+
ram_economy=False,
|
|
280
|
+
args=None,
|
|
281
|
+
info=False,
|
|
282
|
+
):
|
|
283
|
+
|
|
284
|
+
if isinstance(x_data, np.ndarray):
|
|
285
|
+
assert np.ndim(x_data) == 2
|
|
286
|
+
self.input_space_dim = x_data.shape[1]
|
|
287
|
+
else: self.input_space_dim = 1
|
|
288
|
+
|
|
289
|
+
self.output_num = y_data.shape[1]
|
|
290
|
+
output_space_dim = 1
|
|
291
|
+
###check the output dims
|
|
292
|
+
|
|
293
|
+
if np.ndim(y_data) == 1:
|
|
294
|
+
raise ValueError("The output number is 1, you can use GP for single-task GPs")
|
|
295
|
+
if output_space_dim == 1 and isinstance(output_positions, np.ndarray) is False:
|
|
296
|
+
self.output_positions = self._compute_standard_output_positions(len(x_data))
|
|
297
|
+
else:
|
|
298
|
+
self.output_positions = output_positions
|
|
299
|
+
|
|
300
|
+
assert isinstance(self.output_positions, np.ndarray) and np.ndim(self.output_positions) == 2
|
|
301
|
+
self.index_set_dim = self.input_space_dim + output_space_dim
|
|
302
|
+
####transform the space
|
|
303
|
+
self.fvgp_x_data = x_data
|
|
304
|
+
self.fvgp_y_data = y_data
|
|
305
|
+
self.fvgp_noise_variances = noise_variances
|
|
306
|
+
x_data, y_data, noise_variances = self._transform_index_set(x_data, y_data, noise_variances,
|
|
307
|
+
self.output_positions)
|
|
308
|
+
|
|
309
|
+
####init GP
|
|
310
|
+
super().__init__(
|
|
311
|
+
x_data,
|
|
312
|
+
y_data,
|
|
313
|
+
init_hyperparameters=init_hyperparameters,
|
|
314
|
+
noise_variances=noise_variances,
|
|
315
|
+
compute_device=compute_device,
|
|
316
|
+
gp_kernel_function=gp_kernel_function,
|
|
317
|
+
gp_kernel_function_grad=gp_kernel_function_grad,
|
|
318
|
+
gp_mean_function=gp_mean_function,
|
|
319
|
+
gp_mean_function_grad=gp_mean_function_grad,
|
|
320
|
+
gp_noise_function=gp_noise_function,
|
|
321
|
+
gp_noise_function_grad=gp_noise_function_grad,
|
|
322
|
+
gp2Scale=gp2Scale,
|
|
323
|
+
gp2Scale_dask_client=gp2Scale_dask_client,
|
|
324
|
+
gp2Scale_batch_size=gp2Scale_batch_size,
|
|
325
|
+
calc_inv=calc_inv,
|
|
326
|
+
ram_economy=ram_economy,
|
|
327
|
+
args=args,
|
|
328
|
+
info=info)
|
|
329
|
+
|
|
330
|
+
def update_gp_data(
|
|
331
|
+
self,
|
|
332
|
+
x_new,
|
|
333
|
+
y_new,
|
|
334
|
+
noise_variances_new=None,
|
|
335
|
+
append=True,
|
|
336
|
+
output_positions_new=None,
|
|
337
|
+
):
|
|
338
|
+
|
|
339
|
+
"""
|
|
340
|
+
This function updates the data in the gp object instance.
|
|
341
|
+
The data will NOT be appended but overwritten!
|
|
342
|
+
Please provide the full updated data set.
|
|
343
|
+
|
|
344
|
+
Parameters
|
|
345
|
+
----------
|
|
346
|
+
x_new : np.ndarray
|
|
347
|
+
The point positions. Shape (V x D), where D is the `input_space_dim`.
|
|
348
|
+
y_new : np.ndarray
|
|
349
|
+
The values of the data points. Shape (V,1) or (V).
|
|
350
|
+
noise_variances_new : np.ndarray, optional
|
|
351
|
+
An numpy array defining the uncertainties in the data `y_data` in form of a point-wise variance.
|
|
352
|
+
Shape (len(y_data), 1) or (len(y_data)).
|
|
353
|
+
Note: if no variances are provided here, the noise_covariance
|
|
354
|
+
callable will be used; if the callable is not provided the noise variances
|
|
355
|
+
will be set to `abs(np.mean(y_data)) / 100.0`. If you provided a noise function,
|
|
356
|
+
the noise_variances_new will be ignored.
|
|
357
|
+
append : bool, optional
|
|
358
|
+
Indication whether to append to or overwrite the existing dataset. Default = True.
|
|
359
|
+
In the default case, data will be appended.
|
|
360
|
+
output_positions_new : np.ndarray, optional
|
|
361
|
+
A 3-D numpy array of shape (U x output_number x output_dim), so that
|
|
362
|
+
for each measurement position, the outputs
|
|
363
|
+
are clearly defined by their positions in the output space.
|
|
364
|
+
The default is np.array([[0,1,2,3,...,output_number - 1],[0,1,2,3,...,output_number - 1],...]).
|
|
365
|
+
"""
|
|
366
|
+
|
|
367
|
+
##########################################
|
|
368
|
+
#######prepare value positions############
|
|
369
|
+
##########################################
|
|
370
|
+
if not isinstance(output_positions_new, np.ndarray):
|
|
371
|
+
output_positions_new = self._compute_standard_output_positions(len(x_new))
|
|
372
|
+
######################################
|
|
373
|
+
#####transform to index set###########
|
|
374
|
+
######################################
|
|
375
|
+
x_data, y_data, noise_variances = self._transform_index_set(x_new, y_new, noise_variances_new,
|
|
376
|
+
output_positions_new)
|
|
377
|
+
super().update_gp_data(x_data, y_data, noise_variances, append=append)
|
|
378
|
+
self.output_positions = np.row_stack([self.output_positions, output_positions_new])
|
|
379
|
+
|
|
380
|
+
################################################################################################
|
|
381
|
+
def _compute_standard_output_positions(self, point_number):
|
|
382
|
+
value_pos = np.zeros((point_number, self.output_num))
|
|
383
|
+
for j in range(self.output_num):
|
|
384
|
+
value_pos[:, j] = j
|
|
385
|
+
return value_pos
|
|
386
|
+
|
|
387
|
+
################################################################################################
|
|
388
|
+
def _transform_index_set(self, x_data, y_data, noise_variances, output_positions):
|
|
389
|
+
point_number = len(x_data)
|
|
390
|
+
assert isinstance(x_data, np.ndarray) or isinstance(x_data, list)
|
|
391
|
+
if isinstance(x_data, np.ndarray):
|
|
392
|
+
new_points = np.zeros((point_number * self.output_num, self.index_set_dim))
|
|
393
|
+
else:
|
|
394
|
+
new_points = [0.] * point_number * self.output_num
|
|
395
|
+
new_values = np.zeros((point_number * self.output_num))
|
|
396
|
+
if noise_variances is not None:
|
|
397
|
+
new_variances = np.zeros((point_number * self.output_num))
|
|
398
|
+
else:
|
|
399
|
+
new_variances = None
|
|
400
|
+
for i in range(self.output_num):
|
|
401
|
+
if isinstance(x_data, np.ndarray):
|
|
402
|
+
new_points[i * point_number: (i + 1) * point_number] = np.column_stack([x_data, output_positions[:, i]])
|
|
403
|
+
if isinstance(x_data, list):
|
|
404
|
+
for j in range(len(x_data)):
|
|
405
|
+
new_points[i * point_number + j] = [x_data[j], output_positions[j, i]]
|
|
406
|
+
new_values[i * point_number: (i + 1) * point_number] = y_data[:, i]
|
|
407
|
+
if noise_variances is not None:
|
|
408
|
+
new_variances[i * point_number: (i + 1) * point_number] = noise_variances[:, i]
|
|
409
|
+
|
|
410
|
+
return new_points, new_values, new_variances
|
|
411
|
+
|
|
412
|
+
################################################################################################
|
|
413
|
+
|