SHOGUN  v1.1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
KernelMachine.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 1999-2009 Soeren Sonnenburg
8  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
9  */
10 
12 #include <shogun/lib/Signal.h>
13 #include <shogun/base/Parameter.h>
14 
15 using namespace shogun;
16 
17 #ifndef DOXYGEN_SHOULD_SKIP_THIS
18 struct S_THREAD_PARAM
19 {
20  CKernelMachine* kernel_machine;
21  CLabels* result;
22  int32_t start;
23  int32_t end;
24  bool verbose;
25 };
26 #endif // DOXYGEN_SHOULD_SKIP_THIS
27 
29 : CMachine(), kernel(NULL), use_batch_computation(true), use_linadd(true), use_bias(true)
30 {
31  SG_ADD((CSGObject**) &kernel, "kernel", "", MS_AVAILABLE);
32  SG_ADD(&use_batch_computation, "use_batch_computation",
33  "Batch computation is enabled.", MS_NOT_AVAILABLE);
34  SG_ADD(&use_linadd, "use_linadd", "Linadd is enabled.", MS_NOT_AVAILABLE);
35  SG_ADD(&use_bias, "use_bias", "Bias shall be used.", MS_NOT_AVAILABLE);
36  SG_ADD(&m_bias, "m_bias", "Bias term.", MS_NOT_AVAILABLE);
37  SG_ADD(&m_alpha, "m_alpha", "Array of coefficients alpha.",
39  SG_ADD(&m_svs, "m_svs", "Number of ``support vectors''.", MS_NOT_AVAILABLE);
40 
41  m_bias=0.0;
42 }
43 
45 {
47 
50 }
51 
53 {
54  int32_t num_sv=get_num_support_vectors();
55 
56  if (kernel && kernel->has_property(KP_LINADD) && num_sv>0)
57  {
58  int32_t * sv_idx = SG_MALLOC(int32_t, num_sv);
59  float64_t* sv_weight = SG_MALLOC(float64_t, num_sv);
60 
61  for(int32_t i=0; i<num_sv; i++)
62  {
63  sv_idx[i] = get_support_vector(i) ;
64  sv_weight[i] = get_alpha(i) ;
65  }
66 
67  bool ret = kernel->init_optimization(num_sv, sv_idx, sv_weight) ;
68 
69  SG_FREE(sv_idx);
70  SG_FREE(sv_weight);
71 
72  if (!ret)
73  SG_ERROR( "initialization of kernel optimization failed\n");
74 
75  return ret;
76  }
77  else
78  SG_ERROR( "initialization of kernel optimization failed\n");
79 
80  return false;
81 }
82 
84 {
85  CLabels* lab=NULL;
86 
87  if (!kernel)
88  SG_ERROR( "Kernelmachine can not proceed without kernel!\n");
89 
90  if ( kernel && kernel->get_num_vec_rhs()>0 )
91  {
92  int32_t num_vectors=kernel->get_num_vec_rhs();
93 
94  lab=new CLabels(num_vectors);
95  SG_DEBUG( "computing output on %d test examples\n", num_vectors);
96 
98 
99  if (io->get_show_progress())
100  io->enable_progress();
101  else
102  io->disable_progress();
103 
106  {
107  float64_t* output=SG_MALLOC(float64_t, num_vectors);
108  memset(output, 0, sizeof(float64_t)*num_vectors);
109 
110  if (get_num_support_vectors()>0)
111  {
112  int32_t* sv_idx=SG_MALLOC(int32_t, get_num_support_vectors());
114  int32_t* idx=SG_MALLOC(int32_t, num_vectors);
115 
116  //compute output for all vectors v[0]...v[num_vectors-1]
117  for (int32_t i=0; i<num_vectors; i++)
118  idx[i]=i;
119 
120  for (int32_t i=0; i<get_num_support_vectors(); i++)
121  {
122  sv_idx[i] = get_support_vector(i) ;
123  sv_weight[i] = get_alpha(i) ;
124  }
125 
126  kernel->compute_batch(num_vectors, idx,
127  output, get_num_support_vectors(), sv_idx, sv_weight);
128  SG_FREE(sv_idx);
129  SG_FREE(sv_weight);
130  SG_FREE(idx);
131  }
132 
133  for (int32_t i=0; i<num_vectors; i++)
134  lab->set_label(i, get_bias()+output[i]);
135 
136  SG_FREE(output);
137  }
138  else
139  {
140  int32_t num_threads=parallel->get_num_threads();
141  ASSERT(num_threads>0);
142 
143  if (num_threads < 2)
144  {
145  S_THREAD_PARAM params;
146  params.kernel_machine=this;
147  params.result=lab;
148  params.start=0;
149  params.end=num_vectors;
150  params.verbose=true;
151  apply_helper((void*) &params);
152  }
153 #ifdef HAVE_PTHREAD
154  else
155  {
156  pthread_t* threads = SG_MALLOC(pthread_t, num_threads-1);
157  S_THREAD_PARAM* params = SG_MALLOC(S_THREAD_PARAM, num_threads);
158  int32_t step= num_vectors/num_threads;
159 
160  int32_t t;
161 
162  for (t=0; t<num_threads-1; t++)
163  {
164  params[t].kernel_machine = this;
165  params[t].result = lab;
166  params[t].start = t*step;
167  params[t].end = (t+1)*step;
168  params[t].verbose = false;
169  pthread_create(&threads[t], NULL,
170  CKernelMachine::apply_helper, (void*)&params[t]);
171  }
172 
173  params[t].kernel_machine = this;
174  params[t].result = lab;
175  params[t].start = t*step;
176  params[t].end = num_vectors;
177  params[t].verbose = true;
178  apply_helper((void*) &params[t]);
179 
180  for (t=0; t<num_threads-1; t++)
181  pthread_join(threads[t], NULL);
182 
183  SG_FREE(params);
184  SG_FREE(threads);
185  }
186 #endif
187  }
188 
189 #ifndef WIN32
191  SG_INFO( "prematurely stopped. \n");
192  else
193 #endif
194  SG_DONE();
195  }
196  else
197  return NULL;
198 
199  return lab;
200 }
201 
203 {
204  ASSERT(kernel);
205 
207  {
208  float64_t score = kernel->compute_optimized(num);
209  return score+get_bias();
210  }
211  else
212  {
213  float64_t score=0;
214  for(int32_t i=0; i<get_num_support_vectors(); i++)
215  score+=kernel->kernel(get_support_vector(i), num)*get_alpha(i);
216 
217  return score+get_bias();
218  }
219 }
220 
221 
223 {
224  if (!kernel)
225  SG_ERROR("No kernel assigned!\n");
226 
227  CFeatures* lhs=kernel->get_lhs();
228  if (!lhs || !lhs->get_num_vectors())
229  {
230  SG_UNREF(lhs);
231  SG_ERROR("No vectors on left hand side\n");
232  }
233  kernel->init(lhs, data);
234  SG_UNREF(lhs);
235 
236  return apply();
237 }
238 
240 {
241  S_THREAD_PARAM* params= (S_THREAD_PARAM*) p;
242  CLabels* result=params->result;
243  CKernelMachine* kernel_machine=params->kernel_machine;
244 
245 #ifdef WIN32
246  for (int32_t vec=params->start; vec<params->end; vec++)
247 #else
248  for (int32_t vec=params->start; vec<params->end &&
250 #endif
251  {
252  if (params->verbose)
253  {
254  int32_t num_vectors=params->end - params->start;
255  int32_t v=vec-params->start;
256  if ( (v% (num_vectors/100+1))== 0)
257  SG_SPROGRESS(v, 0.0, num_vectors-1);
258  }
259 
260  result->set_label(vec, kernel_machine->apply(vec));
261  }
262 
263  return NULL;
264 }
265 
267 {
268  if (!kernel)
269  SG_ERROR("kernel is needed to store SV features.\n");
270 
271  CFeatures* lhs=kernel->get_lhs();
272  CFeatures* rhs=kernel->get_rhs();
273 
274  if (!lhs)
275  SG_ERROR("kernel lhs is needed to store SV features.\n");
276 
277  /* copy sv feature data */
278  CFeatures* sv_features=lhs->copy_subset(m_svs);
279  SG_UNREF(lhs);
280 
281  /* now sv indices are just the identity */
283 
284  /* set new lhs to kernel */
285  kernel->init(sv_features, rhs);
286 
287  SG_UNREF(rhs);
288 }

SHOGUN Machine Learning Toolbox - Documentation