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 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
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
00108 float64_t* all_bs=new float64_t[num_classes];
00109 memset(all_bs,0,num_classes*sizeof(float64_t));
00110
00111
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 }