10
10
from gpflow .kullback_leiblers import gauss_kl
11
11
from gpflow .mean_functions import Linear , Zero
12
12
from gpflow .params import Parameter , Parameterized , ParamList
13
+ from gpflow .features import inducingpoint_wrapper
13
14
14
- from .utils import shape_as_list
15
15
16
16
class Layer (Parameterized ):
17
17
"""
@@ -34,18 +34,18 @@ def __init__(self, input_dim, output_dim, num_inducing, kernel,
34
34
self .output_dim = output_dim
35
35
self .num_inducing = num_inducing
36
36
if multitask :
37
- self .Z = Parameter (np .zeros ((self .num_inducing , self .input_dim + 1 )),
38
- fix_shape = True )
37
+ Z = np .zeros ((self .num_inducing , self .input_dim + 1 ))
39
38
else :
40
- self .Z = Parameter (np .zeros ((self .num_inducing , self .input_dim )),
41
- fix_shape = True )
39
+ Z = np .zeros ((self .num_inducing , self .input_dim ))
40
+
41
+ self .feature = inducingpoint_wrapper (None , Z )
42
42
43
43
if isinstance (kernel , list ):
44
44
self .kernel = ParamList (kernel )
45
45
else :
46
46
self .kernel = kernel
47
47
48
- self .mean_function = mean_function or Zero ()
48
+ self .mean_function = mean_function or Zero (output_dim = self . output_dim )
49
49
50
50
shape = (self .num_inducing , self .output_dim )
51
51
@@ -63,10 +63,7 @@ def build_prior_KL(self, K):
63
63
def _build_predict (self , Xnew , full_cov = False , stochastic = True ):
64
64
# Credits to High Salimbeni for this (@hughsalimbeni)
65
65
def f_conditional (Xnew , full_cov = False ):
66
- mean , var = conditional (Xnew = Xnew ,
67
- X = self .Z ,
68
- kern = self .kernel ,
69
- f = self .q_mu ,
66
+ mean , var = conditional (Xnew , self .feature , self .kernel , self .q_mu ,
70
67
q_sqrt = self .q_sqrt ,
71
68
full_cov = full_cov ,
72
69
white = True )
@@ -75,14 +72,17 @@ def f_conditional(Xnew, full_cov=False):
75
72
76
73
def multisample_conditional (Xnew , full_cov = False ):
77
74
if full_cov :
78
- f = lambda a : f_conditional (a , full_cov = full_cov )
75
+ def f (a ):
76
+ m , v = f_conditional (a , full_cov = full_cov )
77
+ return m , tf .transpose (v )
78
+ #f = lambda a: f_conditional(a, full_cov=full_cov)
79
79
mean , var = tf .map_fn (f , Xnew , dtype = (settings .tf_float ,
80
- settings .tf_float ))
80
+ settings .tf_float ))
81
81
return tf .stack (mean ), tf .stack (var )
82
82
else :
83
- #S, N, D = shape_as_list(Xnew)
83
+ # S, N, D = shape_as_list(Xnew)
84
84
s = tf .shape (Xnew )
85
- X_flat = tf .reshape (Xnew , [s [0 ]* s [1 ], s [2 ]])
85
+ X_flat = tf .reshape (Xnew , [s [0 ] * s [1 ], s [2 ]])
86
86
mean , var = f_conditional (X_flat )
87
87
return [tf .reshape (m , [s [0 ], s [1 ], - 1 ]) for m in [mean , var ]]
88
88
@@ -93,6 +93,7 @@ def multisample_conditional(Xnew, full_cov=False):
93
93
94
94
return mean , var
95
95
96
+
96
97
def find_weights (input_dim , output_dim , X , multitask = False ):
97
98
"""
98
99
Find the initial weights of the Linear mean function based on
@@ -104,7 +105,7 @@ def find_weights(input_dim, output_dim, X, multitask=False):
104
105
105
106
elif input_dim > output_dim :
106
107
if multitask :
107
- _ , _ , V = np .linalg .svd (X [:,:- 1 ], full_matrices = False )
108
+ _ , _ , V = np .linalg .svd (X [:, :- 1 ], full_matrices = False )
108
109
else :
109
110
_ , _ , V = np .linalg .svd (X , full_matrices = False )
110
111
W = V [:output_dim , :].T
@@ -115,15 +116,17 @@ def find_weights(input_dim, output_dim, X, multitask=False):
115
116
W = np .concatenate ([I , zeros ], 1 )
116
117
117
118
if multitask :
118
- W = np .concatenate ([W , np .zeros ((1 ,W .shape [1 ]))], axis = 0 )
119
+ W = np .concatenate ([W , np .zeros ((1 , W .shape [1 ]))], axis = 0 )
119
120
120
121
return W
121
122
123
+
122
124
class InputMixin (object ):
123
125
"""
124
126
Mixin class for input layers. Implements a single method to compute the
125
127
value of the inputs and inducing inputs for the next layer.
126
128
"""
129
+
127
130
def compute_inputs (self , X , Z , multitask = False ):
128
131
W = find_weights (self .input_dim , self .output_dim , X , multitask )
129
132
@@ -132,44 +135,49 @@ def compute_inputs(self, X, Z, multitask=False):
132
135
133
136
return X_running , Z_running , W
134
137
138
+
135
139
class HiddenMixin (object ):
136
140
"""
137
141
Mixin class for hidden layers. Implements a single method to compute the
138
142
value of the inputs and inducing inputs for the next layer.
139
143
"""
144
+
140
145
def compute_inputs (self , X , Z , multitask = False ):
141
146
W = find_weights (self .input_dim , self .output_dim , X , multitask )
142
147
143
- if isinstance (self .Z , ParamList ):
144
- Z_running = self .Z [0 ].value .copy ().dot (W )
148
+ if isinstance (self .feature , ParamList ):
149
+ Z_running = self .feature [0 ]. Z .value .copy ().dot (W )
145
150
else :
146
- Z_running = self .Z .value .copy ().dot (W )
151
+ Z_running = self .feature . Z .value .copy ().dot (W )
147
152
148
153
X_running = X .copy ().dot (W )
149
154
150
155
return X_running , Z_running , W
151
156
157
+
152
158
class OutputMixin (object ):
153
159
"""
154
160
Mixin class for output layers. Does not implement any methods. Only used
155
161
for type checking.
156
162
"""
163
+
157
164
def compute_inputs (self , X , Z , multitask = False ):
158
165
W = find_weights (self .input_dim , self .output_dim , X , multitask )
159
166
160
- Z_running = self .Z .value .copy ().dot (W )
167
+ Z_running = self .feature . Z .value .copy ().dot (W )
161
168
X_running = X .copy ().dot (W )
162
169
163
170
return X_running , Z_running , W
164
171
172
+
165
173
class InputLayer (Layer , InputMixin ):
166
174
@defer_build ()
167
175
def initialize_forward (self , X , Z , multitask = False ):
168
176
"""
169
177
Initialize Layer and Propagate values of inputs and inducing inputs
170
178
forward
171
179
"""
172
- self .Z .assign (Z )
180
+ self .feature . Z .assign (Z )
173
181
174
182
X_running , Z_running , W = self .compute_inputs (X , Z , multitask )
175
183
@@ -187,7 +195,7 @@ def initialize_forward(self, X, Z, multitask=False):
187
195
Initialize Layer and Propagate values of inputs and inducing inputs
188
196
forward
189
197
"""
190
- self .Z .assign (Z )
198
+ self .feature . Z .assign (Z )
191
199
192
200
X_running , Z_running , W = self .compute_inputs (X , Z , multitask )
193
201
@@ -197,6 +205,7 @@ def initialize_forward(self, X, Z, multitask=False):
197
205
198
206
return X_running , Z_running
199
207
208
+
200
209
class OutputLayer (Layer , OutputMixin ):
201
210
@defer_build ()
202
211
def initialize_forward (self , X , Z , multitask = False ):
@@ -205,5 +214,5 @@ def initialize_forward(self, X, Z, multitask=False):
205
214
forward
206
215
"""
207
216
208
- self .Z .assign (Z )
217
+ self .feature . Z .assign (Z )
209
218
return (None , None )
0 commit comments