00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "lib/io.h"
00012 #include "classifier/svm/GMNPSVM.h"
00013 #include "classifier/svm/gmnplib.h"
00014
00015 #define INDEX(ROW,COL,DIM) (((COL)*(DIM))+(ROW))
00016 #define MINUS_INF INT_MIN
00017 #define PLUS_INF INT_MAX
00018 #define KDELTA(A,B) (A==B)
00019 #define KDELTA4(A1,A2,A3,A4) ((A1==A2)||(A1==A3)||(A1==A4)||(A2==A3)||(A2==A4)||(A3==A4))
00020
00021 CGMNPSVM::CGMNPSVM()
00022 : CMultiClassSVM(ONE_VS_REST)
00023 {
00024 }
00025
00026 CGMNPSVM::CGMNPSVM(float64_t C, CKernel* k, CLabels* lab)
00027 : CMultiClassSVM(ONE_VS_REST, C, k, lab)
00028 {
00029 }
00030
00031 CGMNPSVM::~CGMNPSVM()
00032 {
00033 }
00034
00035 bool CGMNPSVM::train()
00036 {
00037 ASSERT(kernel);
00038 ASSERT(labels && labels->get_num_labels());
00039
00040 int32_t num_data = labels->get_num_labels();
00041 int32_t num_classes = labels->get_num_classes();
00042 int32_t num_virtual_data= num_data*(num_classes-1);
00043
00044 SG_INFO( "%d trainlabels, %d classes\n", num_data, num_classes);
00045
00046 float64_t* vector_y = new float64_t[num_data];
00047 for (int32_t i=0; i<num_data; i++)
00048 {
00049 vector_y[i]= labels->get_label(i)+1;
00050
00051 }
00052
00053 float64_t C = get_C1();
00054 int32_t tmax = 1000000000;
00055 float64_t tolabs = 0;
00056 float64_t tolrel = epsilon;
00057
00058 float64_t reg_const=0;
00059 if( C!=0 )
00060 reg_const = 1/(2*C);
00061
00062
00063 float64_t* alpha = new float64_t[num_virtual_data];
00064 float64_t* vector_c = new float64_t[num_virtual_data];
00065 memset(vector_c, 0, num_virtual_data*sizeof(float64_t));
00066
00067 float64_t thlb = 10000000000.0;
00068 int32_t t = 0;
00069 float64_t* History = NULL;
00070 int32_t verb = 0;
00071
00072 CGMNPLib mnp(vector_y,kernel,num_data, num_virtual_data, num_classes, reg_const);
00073
00074 mnp.gmnp_imdm(vector_c, num_virtual_data, tmax,
00075 tolabs, tolrel, thlb, alpha, &t, &History, verb );
00076
00077
00078 float64_t* all_alphas= new float64_t[num_classes*num_data];
00079 memset(all_alphas,0,num_classes*num_data*sizeof(float64_t));
00080
00081
00082 float64_t* all_bs=new float64_t[num_classes];
00083 memset(all_bs,0,num_classes*sizeof(float64_t));
00084
00085
00086 for(int32_t i=0; i < num_classes; i++ )
00087 {
00088 for(int32_t j=0; j < num_virtual_data; j++ )
00089 {
00090 int32_t inx1=0;
00091 int32_t inx2=0;
00092
00093 mnp.get_indices2( &inx1, &inx2, j );
00094
00095 all_alphas[(inx1*num_classes)+i] +=
00096 alpha[j]*(KDELTA(vector_y[inx1],i+1)-KDELTA(i+1,inx2));
00097 all_bs[i] += alpha[j]*(KDELTA(vector_y[inx1],i+1)-KDELTA(i+1,inx2));
00098 }
00099 }
00100
00101 create_multiclass_svm(num_classes);
00102
00103 for (int32_t i=0; i<num_classes; i++)
00104 {
00105 int32_t num_sv=0;
00106 for (int32_t j=0; j<num_data; j++)
00107 {
00108 if (all_alphas[j*num_classes+i] != 0)
00109 num_sv++;
00110 }
00111 ASSERT(num_sv>0);
00112 SG_DEBUG("svm[%d] has %d sv, b=%f\n", i, num_sv, all_bs[i]);
00113
00114 CSVM* svm=new CSVM(num_sv);
00115
00116 int32_t k=0;
00117 for (int32_t j=0; j<num_data; j++)
00118 {
00119 if (all_alphas[j*num_classes+i] != 0)
00120 {
00121 svm->set_alpha(k, all_alphas[j*num_classes+i]);
00122 svm->set_support_vector(k, j);
00123 k++;
00124 }
00125 }
00126
00127 svm->set_bias(all_bs[i]);
00128 set_svm(i, svm);
00129 }
00130
00131 basealphas.resize(num_classes, ::std::vector<float64_t>(num_data,0));
00132 for(int j=0; j < num_virtual_data; j++ )
00133 {
00134 int inx1=0;
00135 int inx2=0;
00136
00137 mnp.get_indices2( &inx1, &inx2, j );
00138 basealphas[inx2-1][inx1]=alpha[j];
00139 }
00140
00141 delete[] vector_c;
00142 delete[] alpha;
00143 delete[] all_alphas;
00144 delete[] all_bs;
00145 delete[] vector_y;
00146 delete[] History;
00147
00148 return true;
00149 }
00150
00151 void CGMNPSVM::getbasealphas(::std::vector< ::std::vector<float64_t> > & basealphas2)
00152 {
00153 basealphas2=basealphas;
00154 }