Kernels
dkregression.kernels.RBF(x, dist_norm=2, lower_bound_multiplier=0.2, upper_bound_multiplier=5, k_nearest_initial_guess=10)
The radial basis function (RBF) kernel or squared exponential kernel, how it sometimes is also referred to uses a bell curve to calculate the relationship between two points \(x_1, x_2\in\mathbb{R}^d\) in space. It has one (hyper)parameter: the sacale length \(\ell\). Let \(\mathbf{x}_1\in\mathbb{R}^{m\times d}\) be a matrix that represents \(m\) \(d\)-dimensional points and \(\mathbf{x}_2\in\mathbb{R}^{n\times d}\) be a matrix that represents \(n\) \(d\)-dimensional points, then the RBF kernel is defined as: $$ k(\mathbf{x}_1,\mathbf{x}_2)=\exp\left(-\frac{\lVert\mathbf{x}_2 - \mathbf{x}_1\rVert_L^2}{2\ell^2}\right)~. $$ \(L\) is the distance norm used. The kernel matrix is of shape \(k(\mathbf{x}_1,\mathbf{x}_2)\in\mathbb{R}^{n\times m}\).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x |
Tensor
|
Set of data points used to initizalize the kernel. Needs to be two-dimensional of shape |
required |
dist_norm |
float
|
Order of the norm that is used for calculating the pairwise distance between two points. |
2
|
lower_bound_multiplier |
float
|
Factor by which the inital guess for the kernel parameters should be multiplied to obtain a lower bound for the search conducted in |
0.2
|
upper_bound_multiplier |
int
|
Factor by which the inital guess for the kernel parameters should be multiplied to obtain a upper bound for the search conducted in |
5
|
k_nearest_initial_guess |
int
|
The \(k\) used in the heuristic to calculate the average distance between all points in the dataset and their k-nearest point which is used as initial guess for the kernel scale length \(\ell\). |
10
|
Attributes:
| Name | Type | Description |
|---|---|---|
param_names |
list
|
A list of strings that contains the names of the model parameters. For the RBF kernel, this is the scale length 'l'. |
dist_norm |
float
|
The L distance norm to be used to calculate the pairwise distances in the RBF kernel function. Value needs to fulfill |
k_nearest_initial_guess |
int
|
The \(k\) used in the heuristic to calculate teh average distance between all points in the dataset and their k-nearest point which is used as initial guess for the kernel scale length \(\ell\). |
params |
dict
|
Contains the current estimate of the kernel hyperparameter \(\ell\). The keys are defined in |
params_lower_bound |
dict
|
Same keys as defined in |
params_upper_bound |
dict
|
Same keys as defined in |
Examples:
import torch
from dkregression.kernels import RBF
from dkregression.likelihoods import UnivariateGaussianLikelihood
from dkregression.cross_validation import CrossValidation
from dkregression import DKR
X = torch.rand((100,2))
Y = torch.rand((100,1))
kernel = RBF(X,dist_norm=1) # using the L1-norm
likelihood = UnivariateGaussianLikelihood()
cv = CrossValidation()
model = DKR(kernel, likelihood, cv)
model.fit(X,Y)
Source code in src/dkregression/kernels/rbf.py
kernel_matrix(x1, x2, normalize_dim=1)
Returns the kernel matrix for the RBF kernel based on two sets of input points x1, and x2.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x1 |
Tensor
|
First set of input points. Needs to have shape |
required |
x2 |
Tensor
|
First set of input points. Needs to have shape |
required |
normalize_dim |
int
|
Specifies if and in which dimension the kernel matrix should be normalized. |
1
|
Returns:
| Type | Description |
|---|---|
Tensor
|
The kernel matrix of shape |
Examples:
import torch
from dkregression.kernels import RBF
X1 = torch.rand((100,2))
X2 = torch.rand((50,2))
# the initialization is mandatory to set an initial value for the scale length
kernel = RBF(X1)
k = kernel.kernel_matrix(X1,X2)
print(k.shape)
Source code in src/dkregression/kernels/rbf.py
Custom Kernel
It is easily possible to design a custom kernel or implement other kernel functions that are not yet part of the DKRegression package. Doing this requires following the following template.
class CustomKernel():
def __init__(self, x, *args, **kwargs) -> None:
# expect the shape of x to be (n,d)
# a list of the parameters names (as strings), e.g., ["param1", "param2"]
self.param_names = ...
# an initial guess for the kernel parameters based on x. Needs to be
# a dictionary with keys specified in self.param_names.
self.params = ...
# lower bounds for the kernel parameters to be used in `DKR.fit`.
# Needs to be a dictionary with keys specified in self.param_names.
self.params_lower_bound = ...
# upper bounds for the kernel parameters to be used in `DKR.fit`.
# Needs to be a dictionary with keys specified in self.param_names.
self.params_upper_bound = ...
def kernel_matrix(self,x1,x2,normalize_dim=1) -> torch.Tensor:
# expect the shape of x1 to be (n,d) and the shape of x2 to be (m,d).
k = ... # implement the custom kernel function here
# handle the different normalization cases
if normalize_dim in [0,1]:
# if the kernel function is of the type exp(...), consider
# computing log(k) above instead of `k` and use `torch.softmax`.
# See `dkregression.kernels.RBF` this implementation trick.
k /= torch.sum(k,dim=normalize_dim)
elif normalize_dim == -1:
# if using the softmax trick, don't forget to compute
# the exponential of log(k) here.
pass
else:
raise NotImplementedError("The normalization dimension needs to be \
non-negative integer identifying the dimension along which the \
kernel matrix should be normalized or -1 to indicate that no \
normalization should occur.")
return k