source: trunk/src/SVM.cc @ 36

Last change on this file since 36 was 36, checked in by Peter, 19 years ago

stop criteria for the traing modified

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 3.2 KB
Line 
1// $Id: SVM.cc 36 2004-02-12 10:29:21Z peter $
2
3#ifndef _THEP_SVM_
4#define _THEP_SVM_
5
6// System includes
7#include <math.h>
8
9// Thep C++ Tools
10#include "SVM.h"
11#include "matrix.h"
12#include "vector.h"
13#include "random_singleton.h"
14
15using namespace thep_cpp_tools;
16using namespace std;
17
18SVM::SVM(const thep_gsl_api::matrix& kernel, 
19   const thep_gsl_api::vector& target) : trained_(false), 
20                 kernel_(kernel),
21                 target_(target),
22                 alpha_(target.size(),true,true)
23{
24}
25
26void SVM::train() //Should be done so one can choose to not train on all the samples
27{
28  thep_gsl_api::vector E = thep_gsl_api::vector(-target_);
29 
30  double upper_bound = pow(10., 32); 
31  u_int count = 0;
32  double alpha_new;
33  random_singleton* rnd=random_singleton::get_instance();
34  double u;
35  double v;
36  thep_gsl_api::vector dalpha; 
37 
38  // Stop criteria 
39  bool stop_condition = false;
40  while(count<100000 && !stop_condition)
41    {
42     count++; 
43     dalpha = alpha_.mul_elements(target_);
44     E = kernel_*dalpha-target_; //should be done in another way!!
45       
46     // Choosing a pair of variables to modify (Should be done more clever)
47     u_long index1 = rnd->get_uniform_int(kernel_.cols());
48     u_long index2 = rnd->get_uniform_int(kernel_.cols()-1);
49     if (index2 >= index1) 
50      index2++;
51 
52     //Updating the two variables
53     if (target_[index1]!=target_[index2])
54       {       
55  if (alpha_[index2] > alpha_[index1] )
56    {
57    v = upper_bound;
58    u = alpha_[index2] - alpha_[index1];
59    }
60  else
61    {
62     v = upper_bound - alpha_[index1] + alpha_[index2];
63     u = 0;
64    }
65       }
66     else
67       {       
68  if (alpha_[index2] + alpha_[index1] > upper_bound)
69    {
70    u = alpha_[index2] + alpha_[index1] - upper_bound;
71    v = upper_bound;   
72    }
73  else
74    {
75     u = 0;
76     v = alpha_[index1] + alpha_[index2];
77    }
78       }
79
80     double k = kernel_.get(index1, index1) + kernel_.get(index2, index2) - 
81       2*kernel_.get(index1, index2);
82     alpha_new = alpha_[index2] + target_[index2]*
83       (E[index1]-E[index2])/k;
84     if (alpha_new > v)
85       alpha_new = v;
86     else if (alpha_new<u)
87       alpha_new = u;
88     
89     alpha_[index1]+=target_[index1]*target_[index2]*(alpha_[index2]-alpha_new);
90     alpha_[index2]=alpha_new;
91     stop_condition = stop( target_, kernel_, alpha_);
92    }
93 
94  trained_= true;
95}
96
97bool SVM::stop( const thep_gsl_api::vector& target_,
98    const thep_gsl_api::matrix& kernel_,
99    const thep_gsl_api::vector& alpha_)
100{
101  double min_output_positive = 10000;
102  double max_output_negative = -10000;
103  double epsilon = 0.001; // used twice, should perhaps be two different values
104  thep_gsl_api::vector output_unbiased = kernel_ * alpha_.mul_elements(target_);
105  for (u_int i=0; i<target_.size(); i++){
106   if (target_[i]==1){
107     if (output_unbiased[i] < min_output_positive)
108       min_output_positive = output_unbiased[i];
109   }
110   else if( output_unbiased[i] > max_output_negative )
111     max_output_negative = output_unbiased[i];
112   
113  }
114 
115  if (min_output_positive - max_output_negative < 2-epsilon){
116   return false;
117  }
118  else{
119   double primal = alpha_.mul_elements(target_)
120     *  ( alpha_.mul_elements(target_) );
121   double gap = 2 * primal - alpha_.sum();
122   if (gap/(primal+1)<epsilon)
123     return true;
124   else
125     return false;
126  }
127
128
129}
130
131
132
133#endif
Note: See TracBrowser for help on using the repository browser.