Skip to content

Commit 214b83f

Browse files
committed
WIP on the documentation
1 parent 9483210 commit 214b83f

File tree

8 files changed

+134
-31
lines changed

8 files changed

+134
-31
lines changed

docs/create_kernel_plots.jl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,37 @@ using KernelFunctions
66

77
default(lw=3.0,titlefontsize=28,tickfontsize=18)
88

9-
x₀ = 0.0; l=0.1
9+
x₀ = 0.0; l = 0.1
1010
n_grid = 101
1111
fill(x₀,n_grid,1)
1212
xrange = reshape(collect(range(-3,3,length=n_grid)),:,1)
1313

14-
k = SqExponentialKernel(1.0)
14+
k = transform(SqExponentialKernel(),1.0)
1515
K1 = kernelmatrix(k,xrange,obsdim=1)
1616
p = heatmap(K1,yflip=true,colorbar=false,framestyle=:none,background_color=RGBA(0.0,0.0,0.0,0.0))
1717
savefig(joinpath(@__DIR__,"src","assets","heatmap_sqexp.png"))
1818

1919

20-
k = Matern32Kernel(FunctionTransform(x->(sin.(x)).^2))
20+
k = @kernel Matern32Kernel FunctionTransform(x->(sin.(x)).^2)
2121
K2 = kernelmatrix(k,xrange,obsdim=1)
2222
p = heatmap(K2,yflip=true,colorbar=false,framestyle=:none,background_color=RGBA(0.0,0.0,0.0,0.0))
2323
savefig(joinpath(@__DIR__,"src","assets","heatmap_matern.png"))
2424

2525

26-
k = PolynomialKernel(LowRankTransform(randn(3,1)),2.0,0.0)
26+
k = transform(PolynomialKernel(c=0.0,d=2.0),LowRankTransform(randn(3,1)))
2727
K3 = kernelmatrix(k,xrange,obsdim=1)
2828
p = heatmap(K3,yflip=true,colorbar=false,framestyle=:none,background_color=RGBA(0.0,0.0,0.0,0.0))
2929
savefig(joinpath(@__DIR__,"src","assets","heatmap_poly.png"))
3030

31-
k = 0.5*SqExponentialKernel()*LinearKernel(0.5) + 0.4*Matern32Kernel(FunctionTransform(x->sin.(x)))
31+
k = 0.5*SqExponentialKernel()*transform(LinearKernel(),0.5) + 0.4*(@kernel Matern32Kernel() FunctionTransform(x->sin.(x)))
3232
K4 = kernelmatrix(k,xrange,obsdim=1)
3333
p = heatmap(K4,yflip=true,colorbar=false,framestyle=:none,background_color=RGBA(0.0,0.0,0.0,0.0))
3434
savefig(joinpath(@__DIR__,"src","assets","heatmap_prodsum.png"))
3535

3636
plot(heatmap.([K1,K2,K3,K4],yflip=true,colorbar=false)...,layout=(2,2))
3737
savefig(joinpath(@__DIR__,"src","assets","heatmap_combination.png"))
3838

39+
##
3940

4041
for k in [SqExponentialKernel,ExponentialKernel]
4142
K = kernelmatrix(k(),xrange,obsdim=1)

docs/src/assets/heatmap_sqexp.png

1.58 KB
Loading

docs/src/kernels.md

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ The [Square Exponential Kernel](@ref KernelFunctions.SqExponentialKernel) is def
2424

2525
### Gamma Exponential Kernel
2626

27+
The [Gamma Exponential Kernel](@ref KernelFunctions.GammaExponentialKernel) is defined as
2728
```math
2829
k(x,x';\gamma) = \exp\left(-\|x-x'\|^{2\gamma}\right)
2930
```
@@ -32,18 +33,24 @@ The [Square Exponential Kernel](@ref KernelFunctions.SqExponentialKernel) is def
3233

3334
### Matern Kernel
3435

36+
The [Matern Kernel](@ref KernelFunctions.MaternKernel) is defined as
37+
3538
```math
3639
k(x,x';\nu) = \frac{2^{1-\nu}}{\Gamma(\nu)}\left(\sqrt{2\nu}|x-x'|\right)K_\nu\left(\sqrt{2\nu}|x-x'|\right)
3740
```
3841

3942
### Matern 3/2 Kernel
4043

44+
The [Matern 3/2 Kernel](@ref KernelFunctions.Matern32Kernel) is defined as
45+
4146
```math
4247
k(x,x') = \left(1+\sqrt{3}|x-x'|\right)\exp\left(\sqrt{3}|x-x'|\right)
4348
```
4449

4550
### Matern 5/2 Kernel
4651

52+
The [Matern 5/2 Kernel](@ref KernelFunctions.Matern52Kernel) is defined as
53+
4754
```math
4855
k(x,x') = \left(1+\sqrt{5}|x-x'|+\frac{5}{2}\|x-x'\|^2\right)\exp\left(\sqrt{5}|x-x'|\right)
4956
```
@@ -52,12 +59,16 @@ The [Square Exponential Kernel](@ref KernelFunctions.SqExponentialKernel) is def
5259

5360
### Rational Quadratic Kernel
5461

62+
The [Rational Quadratic Kernel](@ref KernelFunctions.RationalQuadraticKernel) is defined as
63+
5564
```math
5665
k(x,x';\alpha) = \left(1+\frac{\|x-x'\|^2}{\alpha}\right)^{-\alpha}
5766
```
5867

5968
### Gamma Rational Quadratic Kernel
6069

70+
The [Gamma Rational Quadratic Kernel](@ref KernelFunctions.GammaRationalQuadraticKernel) is defined as
71+
6172
```math
6273
k(x,x';\alpha,\gamma) = \left(1+\frac{\|x-x'\|^{2\gamma}}{\alpha}\right)^{-\alpha}
6374
```
@@ -66,12 +77,16 @@ The [Square Exponential Kernel](@ref KernelFunctions.SqExponentialKernel) is def
6677

6778
### LinearKernel
6879

80+
The [Linear Kernel](@ref KernelFunctions.LinearKernel) is defined as
81+
6982
```math
7083
k(x,x';c) = \langle x,x'\rangle + c
7184
```
7285

7386
### PolynomialKernel
7487

88+
The [Polynomial Kernel](@ref KernelFunctions.PolynomialKernel) is defined as
89+
7590
```math
7691
k(x,x';c,d) = \left(\langle x,x'\rangle + c\right)^d
7792
```
@@ -80,28 +95,60 @@ The [Square Exponential Kernel](@ref KernelFunctions.SqExponentialKernel) is def
8095

8196
### ConstantKernel
8297

98+
The [Constant Kernel](@ref KernelFunctions.ConstantKernel) is defined as
99+
83100
```math
84101
k(x,x';c) = c
85102
```
86103

87104
### WhiteKernel
88105

106+
The [White Kernel](@ref KernelFunctions.WhiteKernel) is defined as
107+
89108
```math
90109
k(x,x') = \delta(x-x')
91110
```
92111

93112
### ZeroKernel
94113

114+
The [Zero Kernel](@ref KernelFunctions.ZeroKernel) is defined as
115+
95116
```math
96117
k(x,x') = 0
97118
```
98119

99120
# Composite Kernels
100121

101-
## TransformedKernel
122+
### TransformedKernel
123+
124+
The [Transformed Kernel](@ref KernelFunctions.TransformedKernel) is a kernel where input are transformed via a function `f`
125+
126+
```math
127+
k(x,x';f,\widetile{k}) = \widetilde{k}(f(x),f(x'))
128+
```
102129

103-
## ScaledKernel
130+
Where `` is another kernel
104131

105-
## KernelSum
132+
### ScaledKernel
106133

107-
## KernelProduct
134+
The [Scalar Kernel](@ref KernelFunctions.ScaledKernel) is defined as
135+
136+
```math
137+
k(x,x';\sigma^2,\widetilde{k}) = \sigma^2\widetilde{k}(x,x')
138+
```
139+
140+
### KernelSum
141+
142+
The [Kernel Sum](@ref KernelFunctions.KernelSum) is defined as a sum of kernel
143+
144+
```math
145+
k(x,x';\{w_i\},\{k_i\}) = \sum_i w_i k_i(x,x')
146+
```
147+
148+
### KernelProduct
149+
150+
The [Kernel Product](@ref KernelFunctions.KernelProduct) is defined as a product of kernel
151+
152+
```math
153+
k(x,x';\{k_i\}) = \prod_i k_i(x,x')
154+
```

docs/src/transform.md

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,4 @@ You can also create a pipeline of `Transform` via `TransformChain`. For example
66

77
One apply a transformation on a matrix or a vector via `KernelFunctions.apply(t::Transform,v::AbstractVecOrMat)`
88

9-
## Transforms :
10-
```@meta
11-
CurrentModule = KernelFunctions
12-
```
13-
14-
```@docs
15-
IdentityTransform
16-
ScaleTransform
17-
ARDTransform
18-
LowRankTransform
19-
FunctionTransform
20-
ChainTransform
21-
```
9+
Check the list on the [API page](@ref Transforms)

docs/src/userguide.md

Lines changed: 64 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,82 @@ For example to create a square exponential kernel
77
```julia
88
k = SqExponentialKernel()
99
```
10-
All kernels can take as argument a `Transform` object (see [Transform](@ref)) which is directly going to act on the inputs before it's processes.
11-
But it's also possible to simply give a scalar or a vector if all you are interested in is to modify the lengthscale, respectively for all dimensions or independently for each dimension.
10+
Instead of having lengthscale(s) for each kernel we use `Transform` objects (see [Transform](@ref)) which are directly going to act on the inputs before passing them to the kernel.
11+
For example to premultiply the input by 2.0 we create the kernel the following options are possible
12+
```julia
13+
k = transform(SqExponentialKernel(),ScaleTransform(2.0)) # returns a TransformedKernel
14+
k = @kernel SqExponentialKernel() l=2.0 # Will be available soon
15+
k = TransformedKernel(SqExponentialKernel(),ScaleTransform(2.0))
16+
```
17+
Check the [`Transform`](@ref) page to see the other options.
18+
To premultiply the kernel by a variance, you can use `*` or create a `ScaledKernel`
19+
```julia
20+
k = 3.0*SqExponentialKernel()
21+
k = ScaledKernel(SqExponentialKernel(),3.0)
22+
@kernel 3.0*SqExponentialKernel()
23+
```
24+
25+
## Using a kernel function
26+
27+
To compute the kernel function on two vectors you can call
28+
```julia
29+
k = SqExponentialKernel()
30+
x1 = rand(3); x2 = rand(3)
31+
kappa(k,x1,x2) == k(x1,x2) # Syntactic sugar
32+
```
1233

13-
## Kernel matrix creation
34+
## Creating a kernel matrix
1435

15-
Matrix are created via the `kernelmatrix` function or `kerneldiagmatrix`.
36+
Kernel matrices can be created via the `kernelmatrix` function or `kerneldiagmatrix` for only the diagonal.
1637
An important argument to give is the dimensionality of the input `obsdim`. It tells if the matrix is of the type `# samples X # features` (`obsdim`=1) or `# features X # samples`(`obsdim`=2) (similarly to [Distances.jl](https://github.com/JuliaStats/Distances.jl))
1738
For example:
1839
```julia
1940
k = SqExponentialKernel()
2041
A = rand(10,5)
2142
kernelmatrix(k,A,obsdim=1) # Return a 10x10 matrix
2243
kernelmatrix(k,A,obsdim=2) # Return a 5x5 matrix
44+
k(A,obsdim=1) # Syntactic sugar
2345
```
2446

2547
We also support specific kernel matrices outputs:
26-
- For a positive-definite matrix object`PDMat` from [`PDMats.jl`](https://github.com/JuliaStats/PDMats.jl). Call `kernelpdmat(k,A,obsdim=1)`, it will create a matrix and in case of bad conditionning will add some diagonal noise until the matrix is considered PSD, it will then return a `PDMat` object. For this method to work in your code you need to include `using PDMats` first
27-
- For a Kronecker matrix, we rely on [`Kronecker.jl`](https://github.com/MichielStock/Kronecker.jl). We give two methods : `kernelkronmat(k,[x,y,z])` where `x` `y` and `z` are vectors which will return a `KroneckerProduct`, and `kernelkronmat(k,x,dims)` where `x` is a vector and dims and the number of features. Make sure that `k` is a vector compatible with such constructions (with `iskroncompatible`). Both method will return a . For those methods to work in your code you need to include `using Kronecker` first
48+
- For a positive-definite matrix object`PDMat` from [`PDMats.jl`](https://github.com/JuliaStats/PDMats.jl), you can call the following:
49+
```julia
50+
using PDMats
51+
k = SqExponentialKernel()
52+
K = kernelpdmat(k,A,obsdim=1) # PDMat
53+
```
54+
It will create a matrix and in case of bad conditionning will add some diagonal noise until the matrix is considered PSD, it will then return a `PDMat` object. For this method to work in your code you need to include `using PDMats` first
55+
- For a Kronecker matrix, we rely on [`Kronecker.jl`](https://github.com/MichielStock/Kronecker.jl). Here are two examples:
56+
```julia
57+
using Kronecker
58+
x = range(0,1,length=10)
59+
y = range(0,1,length=50)
60+
K = kernelkronmat(k,[x,y]) # Kronecker matrix
61+
K = kernelkronmat(k,x,5) # Kronecker matrix
62+
```
63+
Make sure that `k` is a vector compatible with such constructions (with `iskroncompatible`). Both method will return a . For those methods to work in your code you need to include `using Kronecker` first
64+
- For a Nystrom approximation : `kernelmatrix(nystrom(k, X, ρ, obsdim = 1))` where `ρ` is the proportion of sampled used.
2865

29-
## Kernel manipulation
66+
## Composite kernels
3067

3168
One can create combinations of kernels via `KernelSum` and `KernelProduct` or using simple operators `+` and `*`.
32-
For
69+
For example :
70+
```julia
71+
k1 = SqExponentialKernel()
72+
k2 = Matern32Kernel()
73+
k = 0.5*k1 + 0.2*k2 # KernelSum
74+
k = k1*k2 # KernelProduct
75+
```
76+
77+
## Kernel Parameters
78+
79+
What if you want to differentiate through the kernel parameters? Even in a highly nested structure such as :
80+
```julia
81+
k = transform(0.5*SqExponentialKernel()*MaternKernel()+0.2*(transform(LinearKernel(),2.0)+PolynomialKernel()),[0.1,0.5])
82+
```
83+
One can get the array of parameters to optimize via `params` from `Flux.jl`
84+
85+
```julia
86+
using Flux
87+
params(k)
88+
```

src/KernelFunctions.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
"""
2+
KernelFunctions. [Github](https://github.com/theogf/KernelFunctions.jl) [Documentation](https://theogf.github.io/KernelFunctions.jl/dev/)
3+
"""
14
module KernelFunctions
25

36
export kernelmatrix, kernelmatrix!, kerneldiagmatrix, kerneldiagmatrix!, kappa
@@ -58,7 +61,7 @@ include("zygote_adjoints.jl")
5861
function __init__()
5962
@require Kronecker="2c470bb0-bcc8-11e8-3dad-c9649493f05e" include("matrix/kernelkroneckermat.jl")
6063
@require PDMats="90014a1f-27ba-587c-ab20-58faa44d9150" include("matrix/kernelpdmat.jl")
61-
@require Flux="587475ba-b771-5e3f-ad9e-33799f191a9c" include("trainable.jl")
64+
@require Flux="587475ba-b771-5e3f-ad9e-33799f191a9c" include("trainable.jl")
6265
end
6366

6467
end

src/kernels/scaledkernel.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
"""
2+
`ScaledKernel(k::Kernel,σ²::Real)`
3+
Return a kernel premultiplied by the variance `σ²` : `σ² k(x,x')`
4+
"""
15
struct ScaledKernel{Tk<:Kernel, Tσ²<:Real} <: Kernel
26
kernel::Tk
37
σ²::Vector{Tσ²}

src/kernels/transformedkernel.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
"""
2+
`TransformedKernel(k::Kernel,t::Transform)`
3+
Return a kernel where inputs are pretransformed by `t` : `k(t(x),t(x'))`
4+
"""
15
struct TransformedKernel{Tk<:Kernel,Tr<:Transform} <: Kernel
26
kernel::Tk
37
transform::Tr

0 commit comments

Comments
 (0)