SHOGUN v0.9.0
|
00001 /* 00002 * This program is free software; you can redistribute it and/or modify 00003 * it under the terms of the GNU General Public License as published by 00004 * the Free Software Foundation; either version 3 of the License, or 00005 * (at your option) any later version. 00006 * 00007 * Written (W) 1999-2008 Vojtech Franc, xfrancv@cmp.felk.cvut.cz 00008 * Copyright (C) 1999-2008 Center for Machine Perception, CTU FEL Prague 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 using namespace shogun; 00022 00023 CGMNPSVM::CGMNPSVM() 00024 : CMultiClassSVM(ONE_VS_REST) 00025 { 00026 init(); 00027 } 00028 00029 CGMNPSVM::CGMNPSVM(float64_t C, CKernel* k, CLabels* lab) 00030 : CMultiClassSVM(ONE_VS_REST, C, k, lab) 00031 { 00032 init(); 00033 } 00034 00035 CGMNPSVM::~CGMNPSVM() 00036 { 00037 if (m_basealphas != NULL) delete[] m_basealphas; 00038 } 00039 00040 void 00041 CGMNPSVM::init(void) 00042 { 00043 m_parameters->add_matrix(&m_basealphas, 00044 &m_basealphas_y, &m_basealphas_x, 00045 "m_basealphas", 00046 "Is the basic untransformed alpha."); 00047 00048 m_basealphas = NULL, m_basealphas_y = 0, m_basealphas_x = 0; 00049 } 00050 00051 bool CGMNPSVM::train(CFeatures* data) 00052 { 00053 ASSERT(kernel); 00054 ASSERT(labels && labels->get_num_labels()); 00055 00056 if (data) 00057 { 00058 if (data->get_num_vectors() != labels->get_num_labels()) 00059 { 00060 SG_ERROR("Numbert of vectors (%d) does not match number of labels (%d)\n", 00061 data->get_num_vectors(), labels->get_num_labels()); 00062 } 00063 kernel->init(data, data); 00064 } 00065 00066 int32_t num_data = labels->get_num_labels(); 00067 int32_t num_classes = labels->get_num_classes(); 00068 int32_t num_virtual_data= num_data*(num_classes-1); 00069 00070 SG_INFO( "%d trainlabels, %d classes\n", num_data, num_classes); 00071 00072 float64_t* vector_y = new float64_t[num_data]; 00073 for (int32_t i=0; i<num_data; i++) 00074 { 00075 vector_y[i]= labels->get_label(i)+1; 00076 00077 } 00078 00079 float64_t C = get_C1(); 00080 int32_t tmax = 1000000000; 00081 float64_t tolabs = 0; 00082 float64_t tolrel = epsilon; 00083 00084 float64_t reg_const=0; 00085 if( C!=0 ) 00086 reg_const = 1/(2*C); 00087 00088 00089 float64_t* alpha = new float64_t[num_virtual_data]; 00090 float64_t* vector_c = new float64_t[num_virtual_data]; 00091 memset(vector_c, 0, num_virtual_data*sizeof(float64_t)); 00092 00093 float64_t thlb = 10000000000.0; 00094 int32_t t = 0; 00095 float64_t* History = NULL; 00096 int32_t verb = 0; 00097 00098 CGMNPLib mnp(vector_y,kernel,num_data, num_virtual_data, num_classes, reg_const); 00099 00100 mnp.gmnp_imdm(vector_c, num_virtual_data, tmax, 00101 tolabs, tolrel, thlb, alpha, &t, &History, verb); 00102 00103 /* matrix alpha [num_classes x num_data] */ 00104 float64_t* all_alphas= new float64_t[num_classes*num_data]; 00105 memset(all_alphas,0,num_classes*num_data*sizeof(float64_t)); 00106 00107 /* bias vector b [num_classes x 1] */ 00108 float64_t* all_bs=new float64_t[num_classes]; 00109 memset(all_bs,0,num_classes*sizeof(float64_t)); 00110 00111 /* compute alpha/b from virt_data */ 00112 for(int32_t i=0; i < num_classes; i++ ) 00113 { 00114 for(int32_t j=0; j < num_virtual_data; j++ ) 00115 { 00116 int32_t inx1=0; 00117 int32_t inx2=0; 00118 00119 mnp.get_indices2( &inx1, &inx2, j ); 00120 00121 all_alphas[(inx1*num_classes)+i] += 00122 alpha[j]*(KDELTA(vector_y[inx1],i+1)-KDELTA(i+1,inx2)); 00123 all_bs[i] += alpha[j]*(KDELTA(vector_y[inx1],i+1)-KDELTA(i+1,inx2)); 00124 } 00125 } 00126 00127 create_multiclass_svm(num_classes); 00128 00129 for (int32_t i=0; i<num_classes; i++) 00130 { 00131 int32_t num_sv=0; 00132 for (int32_t j=0; j<num_data; j++) 00133 { 00134 if (all_alphas[j*num_classes+i] != 0) 00135 num_sv++; 00136 } 00137 ASSERT(num_sv>0); 00138 SG_DEBUG("svm[%d] has %d sv, b=%f\n", i, num_sv, all_bs[i]); 00139 00140 CSVM* svm=new CSVM(num_sv); 00141 00142 int32_t k=0; 00143 for (int32_t j=0; j<num_data; j++) 00144 { 00145 if (all_alphas[j*num_classes+i] != 0) 00146 { 00147 svm->set_alpha(k, all_alphas[j*num_classes+i]); 00148 svm->set_support_vector(k, j); 00149 k++; 00150 } 00151 } 00152 00153 svm->set_bias(all_bs[i]); 00154 set_svm(i, svm); 00155 } 00156 00157 if (m_basealphas != NULL) delete[] m_basealphas; 00158 m_basealphas_y = num_classes, m_basealphas_x = num_data; 00159 m_basealphas = new float64_t[m_basealphas_y*m_basealphas_x]; 00160 for (index_t i=0; i<m_basealphas_y*m_basealphas_x; i++) 00161 m_basealphas[i] = 0.0; 00162 00163 for(index_t j=0; j<num_virtual_data; j++) 00164 { 00165 index_t inx1=0, inx2=0; 00166 00167 mnp.get_indices2(&inx1, &inx2, j); 00168 m_basealphas[inx1*m_basealphas_y + (inx2-1)] = alpha[j]; 00169 } 00170 00171 delete[] vector_c; 00172 delete[] alpha; 00173 delete[] all_alphas; 00174 delete[] all_bs; 00175 delete[] vector_y; 00176 delete[] History; 00177 00178 return true; 00179 } 00180 00181 float64_t* 00182 CGMNPSVM::get_basealphas_ptr(index_t* y, index_t* x) 00183 { 00184 if (y == NULL || x == NULL) return NULL; 00185 00186 *y = m_basealphas_y, *x = m_basealphas_x; 00187 return m_basealphas; 00188 }