MklKernelTutorial.cpp
Go to the documentation of this file.
2#include <shark/Core/Random.h>
11#include <boost/fusion/algorithm/iteration/fold.hpp>
12#include <boost/fusion/include/as_vector.hpp>
13
14 struct HeterogeneousInputStruct{
15 shark::RealVector rv1;
16 std::size_t st2;
17 shark::RealVector crv3;
18 };
19
20 #ifndef DOXYGEN_SHOULD_SKIP_THIS
21 BOOST_FUSION_ADAPT_STRUCT(
22 HeterogeneousInputStruct,
23 (shark::RealVector, rv1)(std::size_t, st2)(shark::RealVector, crv3)
24 )
25 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
26
27 namespace shark{
28 template<>
29 struct Batch< HeterogeneousInputStruct >{
31 HeterogeneousInputStruct,
32 (shark::RealVector, rv1)(std::size_t, st2)(shark::RealVector, crv3)
33 )
34 };
35 }
36
37using namespace shark;
38using namespace std;
39
40
41
42
43int main(int argc, char** argv)
44{
45
46////////////////////////////////////////////////////////////////////////////////
47////////////////////////////////////////////////////////////////////////////////
48
49 // test points
50 RealVector x1(2);
51 x1(0)=2;
52 x1(1)=1;
53 RealVector x2(2);
54 x2(0)=-2;
55 x2(1)=1;
56
57
58 // initialize kernels
59 DenseRbfKernel baseKernel1( 0.1 );
60 DenseRbfKernel baseKernel2( 0.01 );
61 std::vector< AbstractKernelFunction<RealVector> * > kernels1;
62 kernels1.push_back( &baseKernel1 );
63 kernels1.push_back( &baseKernel2 );
64 DenseWeightedSumKernel kernel1( kernels1 );
65
66////////////////////////////////////////////////////////////////////////////////
67
68 // examine initial state
69 std::cout << endl << " ======================= WeightedSumKernel: ======================= " << std::endl;
70 cout << endl << "kernel1.isAdaptive(0): " << kernel1.isAdaptive(0) << endl;
71 cout << "kernel1.isAdaptive(1): " << kernel1.isAdaptive(1) << endl;
72 cout << "kernel1.numberOfParameters(): " << kernel1.numberOfParameters() << endl;
73 cout << "kernel1.parameterVector(): " << kernel1.parameterVector() << endl;
74 cout << "kernel1.eval(x1,x2): " << kernel1.eval(x1,x2) << endl << endl;
75
76 // change something
77 RealVector new_params_1( kernel1.numberOfParameters() );
78 new_params_1(0) = 1.0;
79 kernel1.setParameterVector( new_params_1 );
80
81 // examine again
82 cout << "kernel1.parameterVector() with 1st parameter set to 1: " << kernel1.parameterVector() << endl;
83 cout << "kernel1.eval(x1,x2): " << kernel1.eval(x1,x2) << endl << endl;
84
85 // change something else
86 kernel1.setAdaptive(0,true);
87
88 // examine once more
89 cout << "kernel1.isAdaptive(0): " << kernel1.isAdaptive(0) << endl;
90 cout << "kernel1.isAdaptive(1): " << kernel1.isAdaptive(1) << endl;
91 cout << "kernel1.numberOfParameters(): " << kernel1.numberOfParameters() << endl;
92 cout << "kernel1.parameterVector(): " << kernel1.parameterVector() << endl<< endl;
93
94 // another change
95 kernel1.setAdaptive(0,false);
96 kernel1.setAdaptive(1,true);
97
98 // examining again
99 cout << "kernel1.isAdaptive(0): " << kernel1.isAdaptive(0) << endl;
100 cout << "kernel1.isAdaptive(1): " << kernel1.isAdaptive(1) << endl;
101 cout << "kernel1.numberOfParameters(): " << kernel1.numberOfParameters() << endl;
102 cout << "kernel1.parameterVector(): " << kernel1.parameterVector() << endl<< endl;
103
104 // last change
105 kernel1.setAdaptiveAll(true);
106
107 // last examination
108 cout << "kernel1.isAdaptive(0): " << kernel1.isAdaptive(0) << endl;
109 cout << "kernel1.isAdaptive(1): " << kernel1.isAdaptive(1) << endl;
110 cout << "kernel1.numberOfParameters(): " << kernel1.numberOfParameters() << endl;
111 cout << "kernel1.parameterVector(): " << kernel1.parameterVector() << endl;
112 cout << "kernel1.eval(x1,x2): " << kernel1.eval(x1,x2) << endl << endl;
113
114////////////////////////////////////////////////////////////////////////////////
115////////////////////////////////////////////////////////////////////////////////
116
117 DenseRbfKernel baseKernel3(0.1);
118 DenseRbfKernel baseKernel4(0.01);
119 std::vector<AbstractKernelFunction<RealVector>* > kernels2;
120 kernels2.push_back(&baseKernel3);
121 kernels2.push_back(&baseKernel4);
122
123 std::vector< std::pair< std::size_t, std::size_t > > indcs_1;
124 indcs_1.push_back( std::make_pair( 0,2 ) );
125 indcs_1.push_back( std::make_pair( 0,2 ) );
126 DenseSubrangeKernel kernel2( kernels2, indcs_1 );
127
128////////////////////////////////////////////////////////////////////////////////
129
130 // examine initial state
131 std::cout << endl << " ======================= SubrangeKernel, full index range: ======================= " << std::endl;
132 cout << endl << "kernel2.isAdaptive(0): " << kernel2.isAdaptive(0) << endl;
133 cout << "kernel2.isAdaptive(1): " << kernel2.isAdaptive(1) << endl;
134 cout << "kernel2.numberOfParameters(): " << kernel2.numberOfParameters() << endl;
135 cout << "kernel2.parameterVector(): " << kernel2.parameterVector() << endl;
136 cout << "kernel2.eval(x1,x2): " << kernel2.eval(x1,x2) << endl << endl;
137
138 // change something
139 RealVector new_params_2( kernel2.numberOfParameters() );
140 new_params_2(0) = 1.0;
141 kernel2.setParameterVector( new_params_2 );
142
143 // examine again
144 cout << "kernel2.parameterVector() with 1st parameter set to 1: " << kernel2.parameterVector() << endl;
145 cout << "kernel2.eval(x1,x2): " << kernel2.eval(x1,x2) << endl << endl;
146
147 // change something else
148 kernel2.setAdaptive(0,true);
149
150 // examine once more
151 cout << "kernel2.isAdaptive(0): " << kernel2.isAdaptive(0) << endl;
152 cout << "kernel2.isAdaptive(1): " << kernel2.isAdaptive(1) << endl;
153 cout << "kernel2.numberOfParameters(): " << kernel2.numberOfParameters() << endl;
154 cout << "kernel2.parameterVector(): " << kernel2.parameterVector() << endl<< endl;
155
156 // another change
157 kernel2.setAdaptive(0,false);
158 kernel2.setAdaptive(1,true);
159
160 // examining again
161 cout << "kernel2.isAdaptive(0): " << kernel2.isAdaptive(0) << endl;
162 cout << "kernel2.isAdaptive(1): " << kernel2.isAdaptive(1) << endl;
163 cout << "kernel2.numberOfParameters(): " << kernel2.numberOfParameters() << endl;
164 cout << "kernel2.parameterVector(): " << kernel2.parameterVector() << endl<< endl;
165
166 // last change
167 kernel2.setAdaptiveAll(true);
168
169 // last examination
170 cout << "kernel2.isAdaptive(0): " << kernel2.isAdaptive(0) << endl;
171 cout << "kernel2.isAdaptive(1): " << kernel2.isAdaptive(1) << endl;
172 cout << "kernel2.numberOfParameters(): " << kernel2.numberOfParameters() << endl;
173 cout << "kernel2.parameterVector(): " << kernel2.parameterVector() << endl;
174 cout << "kernel2.eval(x1,x2): " << kernel2.eval(x1,x2) << endl << endl;
175
176
177////////////////////////////////////////////////////////////////////////////////
178////////////////////////////////////////////////////////////////////////////////
179
180
181 DenseRbfKernel baseKernel5(0.1);
182 DenseRbfKernel baseKernel6(0.01);
183 std::vector<AbstractKernelFunction<RealVector>* > kernels3;
184 kernels3.push_back(&baseKernel5);
185 kernels3.push_back(&baseKernel6);
186
187 std::vector< std::pair< std::size_t, std::size_t > > indcs_2;
188 indcs_2.push_back( std::make_pair( 0,1 ) );
189 indcs_2.push_back( std::make_pair( 1,2 ) );
190 DenseSubrangeKernel kernel3( kernels3, indcs_2 );
191
192////////////////////////////////////////////////////////////////////////////////
193
194 // examine initial state
195 std::cout << endl << " ======================= SubrangeKernel partial index range: ======================= " << std::endl;
196 cout << endl << "kernel3.isAdaptive(0): " << kernel3.isAdaptive(0) << endl;
197 cout << "kernel3.isAdaptive(1): " << kernel3.isAdaptive(1) << endl;
198 cout << "kernel3.numberOfParameters(): " << kernel3.numberOfParameters() << endl;
199 cout << "kernel3.parameterVector(): " << kernel3.parameterVector() << endl;
200 cout << "kernel3.eval(x1,x2): " << kernel3.eval(x1,x2) << endl << endl;
201
202 // change something
203 RealVector new_params_3( kernel3.numberOfParameters() );
204 new_params_3(0) = 1.0;
205 kernel3.setParameterVector( new_params_3 );
206
207 // examine again
208 cout << "kernel3.parameterVector() with 1st parameter set to 1: " << kernel3.parameterVector() << endl;
209 cout << "kernel3.eval(x1,x2): " << kernel3.eval(x1,x2) << endl << endl;
210
211 // change something else
212 kernel3.setAdaptive(0,true);
213
214 // examine once more
215 cout << "kernel3.isAdaptive(0): " << kernel3.isAdaptive(0) << endl;
216 cout << "kernel3.isAdaptive(1): " << kernel3.isAdaptive(1) << endl;
217 cout << "kernel3.numberOfParameters(): " << kernel3.numberOfParameters() << endl;
218 cout << "kernel3.parameterVector(): " << kernel3.parameterVector() << endl<< endl;
219
220 // another change
221 kernel3.setAdaptive(0,false);
222 kernel3.setAdaptive(1,true);
223
224 // examining again
225 cout << "kernel3.isAdaptive(0): " << kernel3.isAdaptive(0) << endl;
226 cout << "kernel3.isAdaptive(1): " << kernel3.isAdaptive(1) << endl;
227 cout << "kernel3.numberOfParameters(): " << kernel3.numberOfParameters() << endl;
228 cout << "kernel3.parameterVector(): " << kernel3.parameterVector() << endl<< endl;
229
230 // last change
231 kernel3.setAdaptiveAll(true);
232
233 // last examination
234 cout << "kernel3.isAdaptive(0): " << kernel3.isAdaptive(0) << endl;
235 cout << "kernel3.isAdaptive(1): " << kernel3.isAdaptive(1) << endl;
236 cout << "kernel3.numberOfParameters(): " << kernel3.numberOfParameters() << endl;
237 cout << "kernel3.parameterVector(): " << kernel3.parameterVector() << endl;
238 cout << "kernel3.eval(x1,x2): " << kernel3.eval(x1,x2) << endl << endl;
239
240////////////////////////////////////////////////////////////////////////////////
241////////////////////////////////////////////////////////////////////////////////
242
243
244 // set dimensions for data
245 std::size_t const num_samples = 2;
246 std::size_t const dim_nonzeros = 2;
247 std::size_t const max_elem_discr_kernel = 3;
248 std::size_t const dim_sparse = 5;
249 // create temporary helper container
250 std::vector<HeterogeneousInputStruct> data( num_samples );
251 // and fill it
252 data[0].rv1.resize( dim_nonzeros ); data[0].crv3.resize( dim_sparse); //size 5
253 data[1].rv1.resize( dim_nonzeros ); data[1].crv3.resize( dim_sparse); //size 5
254 data[0].rv1(0) = 1.0; data[0].rv1(1) = -1.0; data[0].crv3(1) = -0.5; data[0].crv3(4) = 8.0;
255 data[1].rv1(0) = 1.0; data[1].rv1(1) = -2.0; data[1].crv3(1) = 1.0; data[1].crv3(3) = 0.1;
256 data[0].st2 = 1; data[1].st2 = 2;
257 // and use it to create the 'real' dataset
259
260////////////////////////////////////////////////////////////////////////////////
261
262 //create state matrix for the discrete kernel. necessary but not so relevant
263 RealMatrix matK( max_elem_discr_kernel, max_elem_discr_kernel );
264 matK(0,0) = 0.05; matK(1,1) = 1.0; matK(2,2) = 0.5;
265 matK(0,1) = matK(1,0) = 0.2; matK(0,2) = matK(2,0) = 0.4; matK(1,2) = matK(2,1) = 0.6;
266 // set up base kernels
267 DenseRbfKernel baseKernelRV1(0.1);
268 DiscreteKernel baseKernelST2(matK);
269 DenseLinearKernel baseKernelCRV3;
270 MklKernel<HeterogeneousInputStruct> mkl_kernel( boost::fusion::make_vector( &baseKernelRV1, &baseKernelST2, &baseKernelCRV3) );
271
272 // examine initial state
273 std::cout << endl << " ======================= MklKernel: ======================= " << std::endl;
274 cout << endl << "mkl_kernel.isAdaptive(0): " << mkl_kernel.isAdaptive(0) << endl;
275 cout << "mkl_kernel.isAdaptive(1): " << mkl_kernel.isAdaptive(1) << endl;
276 cout << "mkl_kernel.isAdaptive(2): " << mkl_kernel.isAdaptive(2) << endl;
277 cout << "mkl_kernel.numberOfParameters(): " << mkl_kernel.numberOfParameters() << endl;
278 cout << "mkl_kernel.parameterVector(): " << mkl_kernel.parameterVector() << endl;
279 cout << "mkl_kernel.eval( dataset.element(0), dataset.element(1) ): " << mkl_kernel.eval( dataset.element(0), dataset.element(1) ) << endl << endl;
280
281 // change something
282 mkl_kernel.setAdaptiveAll(true);
283 RealVector new_params_4( mkl_kernel.numberOfParameters() );
284 new_params_4(0) = 1.0;
285 new_params_4(2) = 0.2;
286 mkl_kernel.setParameterVector( new_params_4 );
287
288 // examine effects
289 cout << "mkl_kernel.isAdaptive(0): " << mkl_kernel.isAdaptive(0) << endl;
290 cout << "mkl_kernel.isAdaptive(1): " << mkl_kernel.isAdaptive(1) << endl;
291 cout << "mkl_kernel.isAdaptive(2): " << mkl_kernel.isAdaptive(2) << endl;
292 cout << "mkl_kernel.numberOfParameters(): " << mkl_kernel.numberOfParameters() << endl;
293 cout << "mkl_kernel.parameterVector(): " << mkl_kernel.parameterVector() << endl;
294 cout << "mkl_kernel.eval( dataset.element(0), dataset.element(1) ): " << mkl_kernel.eval( dataset.element(0), dataset.element(1) ) << endl << endl;
295
296
297////////////////////////////////////////////////////////////////////////////////
298////////////////////////////////////////////////////////////////////////////////
299
300 std::size_t num_dims = 9;
301 std::size_t num_points = 200;
302 std::vector<RealVector> input(num_points);
303 RealVector v(num_dims);
304 for ( std::size_t i=0; i<num_points; i++ ) {
305 for ( std::size_t j=0; j<num_dims; j++ )
306 v(j) = random::uni(random::globalRng, -1,1);
307 input[i] = v;
308 }
310
311
312 // declare kernels
313 DenseRbfKernel unnormalized_kernel1(0.1);
314 DenseLinearKernel unnormalized_kernel2;
315 DensePolynomialKernel unnormalized_kernel3(2, 1.0);
316 // declare indices
317 std::vector< std::pair< std::size_t, std::size_t > > indices;
318 indices.push_back( std::make_pair( 0,3 ) );
319 indices.push_back( std::make_pair( 3,6 ) );
320 indices.push_back( std::make_pair( 6,9 ) );
321
322 DenseScaledKernel scale( &unnormalized_kernel3 );
324 normalizer.train( scale, rand_data );
325
326
327 std::cout << endl << " ======================= Kernel normalization: ======================= " << std::endl;
328
329 std::cout << endl << "Done training. Factor is " << scale.factor() << std::endl;
330 std::cout << "Mean = " << normalizer.mean() << std::endl;
331 std::cout << "Trace = " << normalizer.trace() << std::endl << std::endl;
332 //check in feature space
333 double control = 0.0;
334 for ( std::size_t i=0; i<num_points; i++ ) {
335 control += scale.eval(input[i], input[i]);
336 for ( std::size_t j=0; j<num_points; j++ ) {
337 control -= scale.eval(input[i],input[j]) / num_points;
338 }
339 }
340 control /= num_points;
341 std::cout << "Resulting variance of scaled Kernel: " << control << std::endl << std::endl;
342
343 std::vector<AbstractKernelFunction<RealVector>* > kernels4;
344 kernels4.push_back( &unnormalized_kernel1 );
345 kernels4.push_back( &unnormalized_kernel2 );
346 kernels4.push_back( &scale );
347 DenseSubrangeKernel kernel4( kernels4, indices );
348 }