SHOGUN  v2.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MKLMulticlass.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) 2009 Alexander Binder
8  * Copyright (C) 2009 Fraunhofer Institute FIRST and Max-Planck-Society
9  */
10 
13 #include <shogun/io/SGIO.h>
15 
16 using namespace shogun;
17 
18 
21 {
22  svm=NULL;
23  lpw=NULL;
24 
25  mkl_eps=0.01;
27  pnorm=1;
28 }
29 
32 {
33  svm=NULL;
34  lpw=NULL;
35 
36  mkl_eps=0.01;
38  pnorm=1;
39 }
40 
41 
43 {
44  SG_UNREF(svm);
45  svm=NULL;
46  delete lpw;
47  lpw=NULL;
48 }
49 
52 {
53  svm=NULL;
54  lpw=NULL;
55  SG_ERROR(
56  " CMKLMulticlass::CMKLMulticlass(const CMKLMulticlass & cm): must "
57  "not be called, glpk structure is currently not copyable");
58 }
59 
61 {
62  SG_ERROR(
63  " CMKLMulticlass CMKLMulticlass::operator=(...): must "
64  "not be called, glpk structure is currently not copyable");
65  return (*this);
66 }
67 
68 
70 {
71  if (!m_labels)
72  {
73  SG_ERROR("CMKLMulticlass::initsvm(): the set labels is NULL\n");
74  }
75 
76  SG_UNREF(svm);
77  svm=new CGMNPSVM;
78  SG_REF(svm);
79 
80  svm->set_C(get_C());
82 
83  if (m_labels->get_num_labels()<=0)
84  {
85  SG_ERROR("CMKLMulticlass::initsvm(): the number of labels is "
86  "nonpositive, do not know how to handle this!\n");
87  }
88 
90 }
91 
93 {
94  if (!m_kernel)
95  {
96  SG_ERROR("CMKLMulticlass::initlpsolver(): the set kernel is NULL\n");
97  }
98 
100  {
101  SG_ERROR("CMKLMulticlass::initlpsolver(): given kernel is not of type"
102  " K_COMBINED %d required by Multiclass Mkl \n",
104  }
105 
106  int numker=dynamic_cast<CCombinedKernel *>(m_kernel)->get_num_subkernels();
107 
108  ASSERT(numker>0);
109  /*
110  if (lpw)
111  {
112  delete lpw;
113  }
114  */
115 
116  //lpw=new MKLMulticlassGLPK;
117  if(pnorm>1)
118  {
121  }
122  else
123  {
125  }
126  lpw->setup(numker);
127 
128 }
129 
130 
132  numberofsilpiterations)
133 {
134  if ( (max_num_mkl_iters>0) && (numberofsilpiterations>=max_num_mkl_iters) )
135  {
136  return(true);
137  }
138 
139  if (weightshistory.size()>1)
140  {
141  std::vector<float64_t> wold,wnew;
142 
143  wold=weightshistory[ weightshistory.size()-2 ];
144  wnew=weightshistory.back();
145  float64_t delta=0;
146 
147  ASSERT (wold.size()==wnew.size());
148 
149 
150  if((pnorm<=1)&&(!normweightssquared.empty()))
151  {
152 
153  delta=0;
154  for (size_t i=0;i< wnew.size();++i)
155  {
156  delta+=(wold[i]-wnew[i])*(wold[i]-wnew[i]);
157  }
158  delta=sqrt(delta);
159  SG_SDEBUG("L1 Norm chosen, weight delta %f \n",delta);
160 
161 
162  //check dual gap part for mkl
163  int32_t maxind=0;
164  float64_t maxval=normweightssquared[maxind];
165  delta=0;
166  for (size_t i=0;i< wnew.size();++i)
167  {
168  delta+=normweightssquared[i]*wnew[i];
169  if(wnew[i]>maxval)
170  {
171  maxind=i;
172  maxval=wnew[i];
173  }
174  }
175  delta-=normweightssquared[maxind];
176  delta=fabs(delta);
177  SG_SDEBUG("L1 Norm chosen, MKL part of duality gap %f \n",delta);
178  if( (delta < mkl_eps) && (numberofsilpiterations>=1) )
179  {
180  return(true);
181  }
182 
183 
184 
185  }
186  else
187  {
188  delta=0;
189  for (size_t i=0;i< wnew.size();++i)
190  {
191  delta+=(wold[i]-wnew[i])*(wold[i]-wnew[i]);
192  }
193  delta=sqrt(delta);
194  SG_SDEBUG("Lp Norm chosen, weight delta %f \n",delta);
195 
196  if( (delta < mkl_eps) && (numberofsilpiterations>=1) )
197  {
198  return(true);
199  }
200 
201  }
202  }
203 
204  return(false);
205 }
206 
207 void CMKLMulticlass::addingweightsstep( const std::vector<float64_t> &
208  curweights)
209 {
210 
211  if (weightshistory.size()>2)
212  {
213  weightshistory.erase(weightshistory.begin());
214  }
215 
216  SGVector<float64_t> weights(curweights.size());
217  std::copy(curweights.begin(),curweights.end(),weights.vector);
218 
220 
221  initsvm();
222 
224  svm->train();
225 
226  float64_t sumofsignfreealphas=getsumofsignfreealphas();
227  int32_t numkernels=
228  dynamic_cast<CCombinedKernel *>(m_kernel)->get_num_subkernels();
229 
230 
231  normweightssquared.resize(numkernels);
232  for (int32_t ind=0; ind < numkernels; ++ind )
233  {
235  }
236 
237  lpw->addconstraint(normweightssquared,sumofsignfreealphas);
238 }
239 
241 {
242  std::vector<int> trainlabels2(m_labels->get_num_labels());
243  SGVector<int32_t> lab=((CMulticlassLabels*) m_labels)->get_int_labels();
244  std::copy(lab.vector,lab.vector+lab.vlen, trainlabels2.begin());
245 
246  ASSERT (trainlabels2.size()>0);
247  float64_t sum=0;
248 
249  for (int32_t nc=0; nc< ((CMulticlassLabels*) m_labels)->get_num_classes();++nc)
250  {
251  CSVM * sm=svm->get_svm(nc);
252 
253  float64_t bia=sm->get_bias();
254  sum+= bia*bia;
255 
256  SG_UNREF(sm);
257  }
258 
259  index_t basealphas_y = 0, basealphas_x = 0;
260  float64_t* basealphas = svm->get_basealphas_ptr(&basealphas_y,
261  &basealphas_x);
262 
263  for (size_t lb=0; lb< trainlabels2.size();++lb)
264  {
265  for (int32_t nc=0; nc< ((CMulticlassLabels*) m_labels)->get_num_classes();++nc)
266  {
267  CSVM * sm=svm->get_svm(nc);
268 
269  if ((int)nc!=trainlabels2[lb])
270  {
271  CSVM * sm2=svm->get_svm(trainlabels2[lb]);
272 
273  float64_t bia1=sm2->get_bias();
274  float64_t bia2=sm->get_bias();
275  SG_UNREF(sm2);
276 
277  sum+= -basealphas[lb*basealphas_y + nc]*(bia1-bia2-1);
278  }
279  SG_UNREF(sm);
280  }
281  }
282 
283  return(sum);
284 }
285 
287  const int32_t ind)
288 {
289  CKernel * ker=dynamic_cast<CCombinedKernel *>(m_kernel)->get_kernel(ind);
290 
291  float64_t tmp=0;
292 
293  for (int32_t classindex=0; classindex< ((CMulticlassLabels*) m_labels)->get_num_classes();
294  ++classindex)
295  {
296  CSVM * sm=svm->get_svm(classindex);
297 
298  for (int32_t i=0; i < sm->get_num_support_vectors(); ++i)
299  {
300  float64_t alphai=sm->get_alpha(i);
301  int32_t svindi= sm->get_support_vector(i);
302 
303  for (int32_t k=0; k < sm->get_num_support_vectors(); ++k)
304  {
305  float64_t alphak=sm->get_alpha(k);
306  int32_t svindk=sm->get_support_vector(k);
307 
308  tmp+=alphai*ker->kernel(svindi,svindk)
309  *alphak;
310 
311  }
312  }
313  SG_UNREF(sm);
314  }
315  SG_UNREF(ker);
316  ker=NULL;
317 
318  return(tmp);
319 }
320 
321 
323 {
324  ASSERT(m_kernel);
327  int numcl=((CMulticlassLabels*) m_labels)->get_num_classes();
328 
329  if (data)
330  {
331  if (m_labels->get_num_labels() != data->get_num_vectors())
332  {
333  SG_ERROR("%s::train_machine(): Number of training vectors (%d) does"
334  " not match number of labels (%d)\n", get_name(),
336  }
337  m_kernel->init(data, data);
338  }
339 
340  initlpsolver();
341 
342  weightshistory.clear();
343 
344  int32_t numkernels=
345  dynamic_cast<CCombinedKernel *>(m_kernel)->get_num_subkernels();
346 
347  ::std::vector<float64_t> curweights(numkernels,1.0/numkernels);
348  weightshistory.push_back(curweights);
349 
350  addingweightsstep(curweights);
351 
352  int32_t numberofsilpiterations=0;
353  bool final=false;
354  while (!final)
355  {
356 
357  //curweights.clear();
358  lpw->computeweights(curweights);
359  weightshistory.push_back(curweights);
360 
361 
362  final=evaluatefinishcriterion(numberofsilpiterations);
363  ++numberofsilpiterations;
364 
365  addingweightsstep(curweights);
366 
367  } // while(false==final)
368 
369 
370  //set alphas, bias, support vecs
371  ASSERT(numcl>=1);
372  create_multiclass_svm(numcl);
373 
374  for (int32_t i=0; i<numcl; i++)
375  {
376  CSVM* osvm=svm->get_svm(i);
377  CSVM* nsvm=new CSVM(osvm->get_num_support_vectors());
378 
379  for (int32_t k=0; k<osvm->get_num_support_vectors() ; k++)
380  {
381  nsvm->set_alpha(k, osvm->get_alpha(k) );
382  nsvm->set_support_vector(k,osvm->get_support_vector(k) );
383  }
384  nsvm->set_bias(osvm->get_bias() );
385  set_svm(i, nsvm);
386 
387  SG_UNREF(osvm);
388  osvm=NULL;
389  }
390 
391  SG_UNREF(svm);
392  svm=NULL;
393  if (lpw)
394  {
395  delete lpw;
396  }
397  lpw=NULL;
398  return(true);
399 }
400 
401 
402 
403 
405 {
406  if ( weightshistory.empty() )
407  {
408  numweights=0;
409  return NULL;
410  }
411 
412  std::vector<float64_t> subkerw=weightshistory.back();
413  numweights=weightshistory.back().size();
414 
415  float64_t* res=SG_MALLOC(float64_t, numweights);
416  std::copy(weightshistory.back().begin(), weightshistory.back().end(),res);
417  return res;
418 }
419 
421 {
422  mkl_eps=eps;
423 }
424 
426 {
427  max_num_mkl_iters=maxnum;
428 }
429 
431 {
432  pnorm=norm;
433  if(pnorm<1 )
434  SG_ERROR("CMKLMulticlass::set_mkl_norm(float64_t norm) : parameter pnorm<1");
435 }

SHOGUN Machine Learning Toolbox - Documentation