MklKernelTutorial.cpp
Go to the documentation of this file.
1 #include <shark/Data/Dataset.h>
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::CompressedRealVector 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::CompressedRealVector, 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::CompressedRealVector, crv3)
33  )
34  };
35  }
36 
37 using namespace shark;
38 using namespace std;
39 
40 
41 
42 
43 int 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  CompressedLinearKernel 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  }
309  UnlabeledData<RealVector> rand_data = createDataFromRange( input );
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  }