-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathGaussianProcess.fs
More file actions
148 lines (116 loc) · 5.47 KB
/
Copy pathGaussianProcess.fs
File metadata and controls
148 lines (116 loc) · 5.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
namespace Models
open Tensor
open SymTensor
module GaussianProcess =
/// Kernel Type.
type Kernel =
/// linear kernel
| Linear
/// squared exponential kernel
| SquaredExponential of single*single
/// Gaussian Process hyperparameter type.
[<CustomEquality; NoComparison>]
type HyperPars = {
Kernel: Kernel
MeanFunction: ExprT -> ExprT
CutOutsideRange: bool
} with
override x.Equals(yobj) =
match yobj with
| :? HyperPars as y ->
let v = Expr.var<single> "v" [SizeSpec.symbol "n"]
x.Kernel = y.Kernel &&
x.MeanFunction v = y.MeanFunction v &&
x.CutOutsideRange = y.CutOutsideRange
| _ -> false
override x.GetHashCode() =
hash (x.Kernel, x.CutOutsideRange)
///The dafault hyperparameters.
let defaultHyperPars ={
Kernel = SquaredExponential (1.0f,1.0f)
MeanFunction = (fun x -> Expr.zerosLike x)
CutOutsideRange = false
}
/// Gaussian Process parameters with linear kernel.
type ParsLinear = {
HyperPars: HyperPars
}
/// Gaussian Process parameters with squared exponential kernel.
type ParsSE = {
Lengthscale: ExprT
SignalVariance: ExprT
HyperPars: HyperPars
}
///Iitializes the lengthscale.
let initLengthscale l seed (shp: int64 list) : Tensor<single> =
HostTensor.scalar l
/// Initializes the signal variance.
let initSignalVariance s seed (shp: int64 list) : Tensor<single> =
HostTensor.scalar s
/// Parameter Type of a Gaussian Process dependent on the used Kernel.
type Pars = LinPars of ParsLinear
| SEPars of ParsSE
/// Parameters of the Gaussian Process.
let pars (mb: ModelBuilder<_>) (hp:HyperPars) =
match hp.Kernel with
| Linear -> LinPars {HyperPars = hp}
| SquaredExponential (l,s)-> SEPars { Lengthscale = mb.Param ("Lengthscale" , [], initLengthscale l)
SignalVariance = mb.Param ("SignalVariance" , [], initSignalVariance s)
HyperPars = hp}
/// Calculates covariance matrix between two vectors using linear kernel.
let linearCovariance (x:ExprT) (y:ExprT) =
let x_smpl, y_smpl = ElemExpr.idx2
let xvec, yvec = ElemExpr.arg2<single>
let klin = xvec[x_smpl] * yvec[y_smpl]
let sizeX = Expr.nElems x
let sizeY = Expr.nElems y
Expr.elements [sizeX;sizeY] klin [x; y]
/// Calculates covariance matrix between two vectors using linear kernel.
let squaredExpCovariance (l:ExprT, sigf:ExprT) (x:ExprT) (y:ExprT) =
let x_smpl, y_smpl = ElemExpr.idx2
let xvec, yvec,len,sigmaf = ElemExpr.arg4<single>
let kse = sigmaf[] * exp (-( (xvec[x_smpl] - yvec[y_smpl]) *** 2.0f) / (2.0f * len[] *** 2.0f) )
let sizeX = Expr.nElems x
let sizeY = Expr.nElems y
let kse = Expr.elements [sizeX;sizeY] kse [x; y;l;sigf]
kse
let predict (pars:Pars) x (y:ExprT) sigmaNs xStar =
let covMat z z' =
match pars with
| LinPars _ -> linearCovariance z z'
| SEPars parsSE -> squaredExpCovariance (parsSE.Lengthscale,parsSE.SignalVariance) z z'
let k = (covMat x x)
let kStarStar = covMat xStar xStar
let meanFct,cut =
match pars with
| LinPars parsLin -> parsLin.HyperPars.MeanFunction, parsLin.HyperPars.CutOutsideRange
| SEPars parsSE -> parsSE.HyperPars.MeanFunction, parsSE.HyperPars.CutOutsideRange
let meanX = meanFct x
let meanXStar = meanFct xStar
let k = k + Expr.diagMat sigmaNs
let kInv = Expr.invert k
let kStar = covMat x xStar
let mean =
meanXStar + kStar.T .* kInv .* (y - meanX)
let cov = kStarStar - kStar.T .* kInv .* kStar
let mean =
if cut then
let nTrnSmpls =x.NElems
let nSmpls = xStar.NElems
let xFirst = x.[0] |> Expr.reshape [SizeSpec.broadcastable]|> Expr.broadcast [nSmpls]
let xLast = x.[nTrnSmpls - 1L] |> Expr.reshape [SizeSpec.broadcastable]|> Expr.broadcast [nSmpls]
let yFirst = y.[0] |> Expr.reshape [SizeSpec.broadcastable]|> Expr.broadcast [nSmpls]
let yLast = y.[nTrnSmpls - 1L] |> Expr.reshape [SizeSpec.broadcastable]|> Expr.broadcast [nSmpls]
// let xFirst = x.[0] |> Expr.reshape [SizeSpec.broadcastable]|> Expr.broadcast [nSmpls]
// let xLast = x.[nTrnSmpls - 1] |> Expr.reshape [SizeSpec.broadcastable]|> Expr.broadcast [nSmpls]
// let yFirst = y.[0] |> Expr.reshape [SizeSpec.broadcastable]|> Expr.broadcast [nSmpls]
// let yLast = y.[nTrnSmpls - 1] |> Expr.reshape [SizeSpec.broadcastable]|> Expr.broadcast [nSmpls]
let mean = Expr.ifThenElse (xStar <<<< xFirst) yFirst mean
Expr.ifThenElse (xStar >>>> xLast) yLast mean
else
mean
mean, cov
/// WARNING: NOT YET IMPLEMENTED, ONLY A REMINDER FOR LATER IMPLEMENTATION!
/// !!! CALLING THIS FUNCTION WILL ONLY CAUSE AN ERROR !!!
let logMarginalLiklihood (pars:Pars) x y sigmaNs xStar =
failwith "TODO: implement logMarginalLikelihood"