![]() |
GURLS++
2.0.00
C++ Implementation of GURLS Matlab Toolbox
|
00001 00002 #include "gurls++/nystromwrapper.h" 00003 00004 #include "gurls++/optmatrix.h" 00005 #include "gurls++/predkerneltraintest.h" 00006 #include "gurls++/primal.h" 00007 #include "gurls++/utils.h" 00008 00009 00010 #include "gurls++/macroavg.h" 00011 #include "gurls++/precisionrecall.h" 00012 #include "gurls++/rmse.h" 00013 00014 #include <boost/date_time/posix_time/posix_time_types.hpp> 00015 00016 #include <vector> 00017 00018 namespace gurls 00019 { 00020 00021 template <typename T> 00022 NystromWrapper<T>::NystromWrapper(const std::string& name):KernelWrapper<T>(name) {} 00023 00024 template <typename T> 00025 void NystromWrapper<T>::train(const gMat2D<T> &X, const gMat2D<T> &y) 00026 { 00027 GurlsOptionsList *opt = this->opt; 00028 const bool regression = (this->probType == GurlsWrapper<T>::REGRESSION); 00029 00030 GurlsOptionsList* paramsel = opt->getOptAs<GurlsOptionsList>("paramsel"); 00031 paramsel->removeOpt("X"); 00032 paramsel->removeOpt("C"); 00033 paramsel->removeOpt("n_opt"); 00034 paramsel->removeOpt("guesses"); 00035 paramsel->removeOpt("perf"); 00036 paramsel->removeOpt("perf_train"); 00037 00038 00039 const unsigned long n = X.rows(); 00040 const unsigned long d = X.cols(); 00041 const unsigned long t = y.cols(); 00042 00043 const gMat2D<T> empty; 00044 00045 const double sigma = opt->getOptAsNumber("paramsel.sigma"); 00046 Performance<T> *perfTask = Performance<T>::factory(opt->getOptAsString("hoperf")); 00047 00048 00049 const double n_nystrom = opt->getOptAsNumber("n_nystrom"); 00050 const unsigned long nparams = static_cast<unsigned long>(opt->getOptAsNumber("nlambda")); 00051 00052 00053 const gMat2D<T> *Xtr = NULL; 00054 const gMat2D<T> *ytr = NULL; 00055 const gMat2D<T> *Xva = NULL; 00056 const gMat2D<T> *yva = NULL; 00057 00058 00059 bool split = (nparams > 1); 00060 00061 unsigned long ntr, nva; 00062 00063 if(split) 00064 { 00065 ntr = static_cast<unsigned long>(n*(1.0-opt->getOptAsNumber("hoproportion"))); 00066 nva = n-ntr; 00067 00068 unsigned long* trva = new unsigned long[n]; 00069 randperm(n, trva, true, 0); 00070 00071 unsigned long *tr = trva; 00072 unsigned long *va = trva+ntr; 00073 00074 00075 gMat2D<T> *Xtr_tmp = new gMat2D<T>(ntr, d); 00076 subMatrixFromRows(X.getData(), n, d, tr, ntr, Xtr_tmp->getData()); 00077 Xtr = Xtr_tmp; 00078 00079 gMat2D<T> *ytr_tmp = new gMat2D<T> (ntr, t); 00080 subMatrixFromRows(y.getData(), n, t, tr, ntr, ytr_tmp->getData()); 00081 ytr = ytr_tmp; 00082 00083 gMat2D<T> *Xva_tmp = new gMat2D<T> (nva, d); 00084 subMatrixFromRows(X.getData(), n, d, va, nva, Xva_tmp->getData()); 00085 Xva = Xva_tmp; 00086 00087 gMat2D<T> *yva_tmp = new gMat2D<T> (nva, t); 00088 subMatrixFromRows(y.getData(), n, t, va, nva, yva_tmp->getData()); 00089 yva = yva_tmp; 00090 00091 00092 // delete splitOpt; 00093 delete [] trva; 00094 } 00095 else 00096 { 00097 Xtr = &X; 00098 ytr = &y; 00099 00100 ntr = n; 00101 nva = 0; 00102 } 00103 00104 00105 00106 unsigned long guesses_end = static_cast<unsigned long>(n_nystrom); 00107 00108 std::vector<unsigned long> guesses; 00109 unsigned long step = static_cast<unsigned long>(floor(n_nystrom/nparams)); 00110 for(unsigned long i = guesses_end-1, count = 0; count < nparams; i-=step, ++count) 00111 guesses.push_back(i); 00112 00113 00114 // indices = randperm(ntr); 00115 unsigned long indices_length = 0; 00116 unsigned long *indices = getIndices(y, ntr, t, guesses_end, indices_length); 00117 00118 00119 00120 gMat2D<unsigned long> *indices_mat = new gMat2D<unsigned long>(indices_length, 1); 00121 copy(indices_mat->getData(), indices, indices_length); 00122 paramsel->addOpt("indices", new OptMatrix<gMat2D<unsigned long> >(*indices_mat)); 00123 00124 00125 // vout.perf = zeros(length(guesses),1); 00126 gMat2D<T> *perf_mat = new gMat2D<T>(guesses.size(), 1); 00127 paramsel->addOpt("acc", new OptMatrix<gMat2D<T> >(*perf_mat)); 00128 T* perf_it = perf_mat->getData(); 00129 set(perf_it, (T)-1, guesses.size()); 00130 00131 gMat2D<unsigned long> *times_mat = new gMat2D<unsigned long>(guesses.size(), 1); 00132 paramsel->addOpt("times", new OptMatrix<gMat2D<unsigned long> >(*times_mat)); 00133 unsigned long *times_it = times_mat->getData(); 00134 set(times_it, 0ul, guesses.size()); 00135 00136 00137 00138 // Xsub = zeros(guesses(end),d); 00139 gMat2D<T> *Xsub_mat = new gMat2D<T>(guesses_end, d); 00140 T *Xsub = Xsub_mat->getData(); 00141 set(Xsub, (T)0.0, guesses_end*d); 00142 00143 // K = zeros(ntr,guesses(end)); 00144 // Ktrva = zeros(nva,guesses(end)); 00145 gMat2D<T>* K_mat = NULL; 00146 T *K = NULL; 00147 T* Ktrva = NULL; 00148 00149 if(split) 00150 { 00151 K_mat = new gMat2D<T>(ntr, guesses_end); 00152 K = K_mat->getData(); 00153 set(K, (T)0.0, ntr*guesses_end); 00154 00155 Ktrva = new T[nva*guesses_end]; 00156 set(Ktrva, (T)0.0, nva*guesses_end); 00157 } 00158 00159 // KtK = zeros(guesses(end),guesses(end)); 00160 T* KtK = new T[guesses_end*guesses_end]; 00161 set(KtK, (T)0.0, guesses_end*guesses_end); 00162 00163 // i_init = 1; 00164 unsigned long i_init = 0; 00165 00166 00167 // opt_tmp.paramsel.sigma = opt.paramsel.sigma; 00168 GurlsOptionsList* opt_tmp = new GurlsOptionsList("tmp"); 00169 GurlsOptionsList* tmp_kernel = new GurlsOptionsList("kernel"); 00170 GurlsOptionsList* tmp_paramsel = new GurlsOptionsList("paramsel"); 00171 GurlsOptionsList* tmp_optimizer = new GurlsOptionsList("optimizer"); 00172 00173 opt_tmp->addOpt("kernel", tmp_kernel); 00174 opt_tmp->addOpt("paramsel", tmp_paramsel); 00175 opt_tmp->addOpt("optimizer", tmp_optimizer); 00176 00177 tmp_kernel->addOpt("type", opt->getOptAsString("kernel.type")); 00178 tmp_paramsel->addOpt("sigma", new OptNumber(sigma)); 00179 00180 00181 PredKernelTrainTest<T> predKernelTask; 00182 00183 gMat2D<T> *alpha_mat = new gMat2D<T>(guesses_end, t); 00184 T *const alpha = alpha_mat->getData(); 00185 00186 gMat2D<unsigned long> *guesses_mat = new gMat2D<unsigned long>(guesses.size(), 1); 00187 unsigned long *guesses_mat_it = guesses_mat->getData(); 00188 set(guesses_mat_it, 0ul, guesses.size()); 00189 00190 boost::posix_time::ptime begin, end; 00191 boost::posix_time::time_duration diff; 00192 00193 T prevPerf = (regression)? -std::numeric_limits<T>::max(): 0; 00194 00195 begin = boost::posix_time::microsec_clock::local_time(); 00196 for(std::vector<unsigned long>::iterator it = guesses.begin(); it != guesses.end(); ++it) 00197 { 00198 const unsigned long i = *it; 00199 00200 *guesses_mat_it = i+1; 00201 00202 // Xnew = Xtr(indices(i_init:i_end),:); 00203 const unsigned long nindices = i - i_init + 1; 00204 gMat2D<T> *Xnew = new gMat2D<T>(nindices,d); 00205 subMatrixFromRows(Xtr->getData(), ntr, d, indices+i_init, nindices, Xnew->getData()); 00206 00207 // opt_tmp.rls.X = Xnew; 00208 tmp_optimizer->addOpt("X", new OptMatrix<gMat2D<T> >(*Xnew, false)); 00209 00210 // kernel = predkernel_traintest(Xtr,[],opt_tmp); 00211 GurlsOptionsList *kernel = predKernelTask.execute(*Xtr, empty, *opt_tmp); 00212 00213 gMat2D<T> &predkernel_K = kernel->getOptValue<OptMatrix<gMat2D<T> > >("K"); 00214 00215 if(split) 00216 { 00217 // K(:,i_init:i_end) = kernel.K; 00218 copy(K+(ntr*i_init), predkernel_K.getData(), predkernel_K.getSize()); 00219 } 00220 else 00221 { 00222 OptMatrix<gMat2D<T> > * kk = kernel->getOptAs<OptMatrix<gMat2D<T> > >("K"); 00223 kk->detachValue(); 00224 00225 if(K_mat != NULL) 00226 delete K_mat; 00227 00228 K_mat = &predkernel_K; 00229 K = K_mat->getData(); 00230 } 00231 00232 00233 // KtK(i_init:i_end,i_init:i_end) = kernel.K'*kernel.K; 00234 T* KtK_sub = new T[nindices*nindices]; 00235 00236 dot(predkernel_K.getData(), predkernel_K.getData(), KtK_sub, ntr, nindices, ntr, nindices, nindices, nindices, CblasTrans, CblasNoTrans, CblasColMajor); 00237 for(unsigned long i=0; i< nindices; ++i) 00238 copy(KtK+i_init+((i_init+i)*guesses_end), KtK_sub+(i*nindices), nindices); 00239 00240 delete[] KtK_sub; 00241 00242 00243 // if guesses_c>1 00244 if(it != guesses.begin()) 00245 { 00246 // KtKcol = K(:,1:(i_init-1))'*kernel.K; 00247 T *KtKcol = new T[i_init*nindices]; 00248 dot(K, predkernel_K.getData(), KtKcol, ntr, i_init, ntr, nindices, i_init, nindices, CblasTrans, CblasNoTrans, CblasColMajor); 00249 00250 // KtK(1:(i_init-1),i_init:i_end) = KtKcol; 00251 // KtK(i_init:i_end,1:(i_init-1)) = KtKcol'; 00252 for(unsigned long j=0; j<nindices; ++j) 00253 { 00254 copy(KtK+(guesses_end*(i_init+j)), KtKcol+(i_init*j), i_init); 00255 copy(KtK+i_init+j, KtKcol+(i_init*j), i_init, guesses_end, 1); 00256 } 00257 00258 delete [] KtKcol; 00259 } 00260 00261 delete kernel; 00262 00263 // alpha = pinv(KtK(1:i_end,1:i_end))*(K(:,1:i_end)'*ytr); 00264 00265 const unsigned long ii = i+1; 00266 00267 00268 KtK_sub = new T[ ii*ii]; 00269 for(T *K_it = KtK, *Ks_it = KtK_sub, *const K_end = K_it+(guesses_end*ii); K_it != K_end; K_it+=guesses_end, Ks_it+=ii) 00270 copy(Ks_it, K_it, ii); 00271 00272 int r, c; 00273 T *pinv_K = pinv(KtK_sub, ii, ii, r, c); 00274 delete [] KtK_sub; 00275 00276 T *Kty = new T[ii*t]; 00277 dot(K, ytr->getData(), Kty, ntr, ii, ntr, t, ii, t, CblasTrans, CblasNoTrans, CblasColMajor); 00278 00279 00280 dot(pinv_K, Kty, alpha, ii, ii, ii, t, ii, t, CblasNoTrans, CblasNoTrans, CblasColMajor); 00281 00282 delete [] Kty; 00283 delete [] pinv_K; 00284 00285 00286 if(split) 00287 { 00288 // validation error 00289 // kernel = predkernel_traintest(Xva,[],opt_tmp); 00290 kernel = predKernelTask.execute(*Xva, empty, *opt_tmp); 00291 00292 // Ktrva(:,i_init:i_end) = kernel.K; 00293 const gMat2D<T> &predkernel_Kva = kernel->getOptValue<OptMatrix<gMat2D<T> > >("K"); 00294 copy(Ktrva+(nva*i_init), predkernel_Kva.getData(), predkernel_Kva.getSize()); 00295 delete kernel; 00296 00297 00298 // opt.pred = Ktrva(:,1:i_end)*alpha; 00299 gMat2D<T>* pred = new gMat2D<T>(nva ,t); 00300 dot(Ktrva, alpha, pred->getData(), nva, ii, ii, t, nva, t, CblasNoTrans, CblasNoTrans, CblasColMajor); 00301 opt->addOpt("pred", new OptMatrix<gMat2D<T> >(*pred)); 00302 00303 // perf = opt.hoperf([],yva,opt); 00304 GurlsOptionsList *perf = perfTask->execute(empty, *yva, *opt); 00305 opt->removeOpt("pred"); 00306 00307 if(regression) 00308 *perf_it = static_cast<T>(perf->getOptValue<OptNumber>("forho")); 00309 else 00310 { 00311 // vout.perf(guesses_c) = mean(perf.forho); 00312 const gMat2D<T> &acc = perf->getOptValue<OptMatrix<gMat2D<T> > >("acc"); 00313 00314 *perf_it = sumv(acc.getData(), acc.getSize())/acc.getSize(); 00315 } 00316 00317 00318 delete perf; 00319 } 00320 00321 tmp_optimizer->removeOpt("X"); 00322 00323 // Xsub(i_init:i_end,:) = Xnew; 00324 for(T* Xsub_it = Xsub+i_init, *Xsub_end = Xsub_it+(guesses_end*d), *Xnew_it = Xnew->getData(); Xsub_it != Xsub_end; Xsub_it+=guesses_end, Xnew_it+=nindices) 00325 copy(Xsub_it, Xnew_it, nindices); 00326 00327 00328 delete Xnew; 00329 00330 // i_init = i_end+1; 00331 i_init = i+1; 00332 00333 end = boost::posix_time::microsec_clock::local_time(); 00334 diff = end-begin; 00335 00336 *times_it = static_cast<unsigned long>(diff.total_milliseconds()); 00337 ++times_it; 00338 00339 if(le(*perf_it, prevPerf) && i > 10) 00340 break; 00341 else 00342 { 00343 prevPerf = *perf_it; 00344 00345 ++perf_it; 00346 ++guesses_mat_it; 00347 } 00348 } 00349 00350 if(split) 00351 { 00352 delete Xtr; 00353 delete ytr; 00354 delete Xva; 00355 delete yva; 00356 00357 delete [] Ktrva; 00358 } 00359 00360 delete K_mat; 00361 00362 delete [] indices; 00363 delete [] KtK; 00364 00365 delete perfTask; 00366 delete opt_tmp; 00367 00368 00369 unsigned long nsub; 00370 00371 if(guesses_mat_it - guesses_mat->getData() < guesses_mat->getSize()-1) 00372 { 00373 nsub = *guesses_mat_it; 00374 gMat2D<T> *Xsub_mat_sub = new gMat2D<T>(nsub, d); 00375 00376 const unsigned long size = nsub*d; 00377 00378 for(T* it = Xsub_mat_sub->getData(), *end = it+(size), *X_it = Xsub_mat->getData(); it != end; it+=nsub, X_it+=guesses_end) 00379 copy(it, X_it, nsub); 00380 00381 delete Xsub_mat; 00382 Xsub_mat = Xsub_mat_sub; 00383 } 00384 else 00385 nsub = guesses_end; 00386 00387 00388 // vout.X = Xsub(1:i_end,:); 00389 paramsel->addOpt("X", new OptMatrix<gMat2D<T> >(*Xsub_mat)); 00390 00391 // vout.C = alpha; 00392 paramsel->addOpt("C", new OptMatrix<gMat2D<T> >(*alpha_mat)); 00393 00394 // [dummy,vout.n_opt] = max(vout.perf); 00395 paramsel->addOpt("n_opt", new OptNumber(*std::max_element(perf_mat->getData(), perf_mat->getData()+perf_mat->getSize()))); 00396 00397 // vout.guesses = guesses; 00398 paramsel->addOpt("guesses", new OptMatrix<gMat2D<unsigned long> >(*guesses_mat)); 00399 00400 } 00401 00402 template <typename T> 00403 void NystromWrapper<T>::train_largescale(const gMat2D<T> &X, const gMat2D<T> &y) 00404 { 00405 GurlsOptionsList *opt = this->opt; 00406 00407 GurlsOptionsList* paramsel = opt->getOptAs<GurlsOptionsList>("paramsel"); 00408 paramsel->removeOpt("X"); 00409 paramsel->removeOpt("C"); 00410 paramsel->removeOpt("n_opt"); 00411 paramsel->removeOpt("guesses"); 00412 paramsel->removeOpt("acc"); 00413 paramsel->removeOpt("times"); 00414 paramsel->removeOpt("indices"); 00415 00416 00417 const unsigned long n = X.rows(); 00418 const unsigned long d = X.cols(); 00419 const unsigned long t = y.cols(); 00420 00421 const gMat2D<T> empty; 00422 00423 const double sigma = opt->getOptAsNumber("paramsel.sigma"); 00424 00425 const double n_nystrom = opt->getOptAsNumber("n_nystrom"); 00426 // B = opt.nystrom_blocksize; 00427 const unsigned long B = static_cast<unsigned long>(opt->getOptAsNumber("nlambda")); 00428 00429 const gMat2D<T> *Xtr = &X; 00430 const gMat2D<T> *ytr = &y; 00431 00432 unsigned long ntr = n; 00433 00434 00435 unsigned long guesses_end = static_cast<unsigned long>(n_nystrom); 00436 00437 // guesses = B:B:opt.rank_max; 00438 std::vector<unsigned long> guesses; 00439 for(unsigned long i = B-1; i < guesses_end; i+=B) 00440 guesses.push_back(i); 00441 00442 guesses_end = *(guesses.rbegin())+1; 00443 00444 // indices = randperm(ntr); 00445 unsigned long indices_length = 0; 00446 unsigned long *indices = getIndices(y, ntr, t, guesses_end, indices_length); 00447 00448 00449 00450 gMat2D<unsigned long> *indices_mat = new gMat2D<unsigned long>(indices_length, 1); 00451 copy(indices_mat->getData(), indices, indices_length); 00452 paramsel->addOpt("indices", new OptMatrix<gMat2D<unsigned long> >(*indices_mat)); 00453 00454 00455 gMat2D<unsigned long> *times_mat = new gMat2D<unsigned long>(guesses.size(), 1); 00456 paramsel->addOpt("times", new OptMatrix<gMat2D<unsigned long> >(*times_mat)); 00457 unsigned long *times_it = times_mat->getData(); 00458 set(times_it, 0ul, guesses.size()); 00459 00460 00461 00462 // Xsub = zeros(guesses(end),d); 00463 gMat2D<T> *Xsub_mat = new gMat2D<T>(guesses_end, d); 00464 T *Xsub = Xsub_mat->getData(); 00465 set(Xsub, (T)0.0, guesses_end*d); 00466 00467 // KtK = zeros(guesses(end),guesses(end)); 00468 T *KtK = new T[guesses_end*guesses_end]; 00469 set(KtK, (T)0.0, guesses_end*guesses_end); 00470 00471 // Kty = zeros(guesses(end),T); 00472 T *Kty = new T[guesses_end*t]; 00473 set(Kty, (T)0.0, guesses_end*t); 00474 00475 // i_init = 1; 00476 unsigned long i_init = 0; 00477 00478 00479 // opt_tmp.paramsel.sigma = opt.paramsel.sigma; 00480 // opt_tmp.kernel.type = opt.kernel.type; 00481 00482 GurlsOptionsList* opt_tmp = new GurlsOptionsList("tmp"); 00483 GurlsOptionsList* tmp_kernel = new GurlsOptionsList("kernel"); 00484 GurlsOptionsList* tmp_paramsel = new GurlsOptionsList("paramsel"); 00485 GurlsOptionsList* tmp_optimizer = new GurlsOptionsList("optimizer"); 00486 00487 opt_tmp->addOpt("kernel", tmp_kernel); 00488 opt_tmp->addOpt("paramsel", tmp_paramsel); 00489 opt_tmp->addOpt("optimizer", tmp_optimizer); 00490 00491 tmp_kernel->addOpt("type", opt->getOptAsString("kernel.type")); 00492 tmp_paramsel->addOpt("sigma", new OptNumber(sigma)); 00493 00494 00495 PredKernelTrainTest<T> predKernelTask; 00496 00497 gMat2D<T> *alpha_mat = new gMat2D<T>(guesses_end, t); 00498 T *const alpha = alpha_mat->getData(); 00499 00500 gMat2D<unsigned long> *guesses_mat = new gMat2D<unsigned long>(guesses.size(), 1); 00501 unsigned long *guesses_mat_it = guesses_mat->getData(); 00502 set(guesses_mat_it, 0ul, guesses.size()); 00503 00504 boost::posix_time::ptime begin, end; 00505 boost::posix_time::time_duration diff; 00506 00507 begin = boost::posix_time::microsec_clock::local_time(); 00508 for(std::vector<unsigned long>::iterator it = guesses.begin(); it != guesses.end(); ++it) 00509 { 00510 const unsigned long i = *it; 00511 *guesses_mat_it = i+1; 00512 00513 // Xnew = Xtr(indices(i_init:i_end),:); 00514 const unsigned long nindices = i - i_init + 1; 00515 gMat2D<T> *Xnew = new gMat2D<T>(nindices,d); 00516 subMatrixFromRows(Xtr->getData(), ntr, d, indices+i_init, nindices, Xnew->getData()); 00517 00518 // opt_tmp.rls.X = Xnew; 00519 tmp_optimizer->addOpt("X", new OptMatrix<gMat2D<T> >(*Xnew, false)); 00520 00521 // kernel_col = predkernel_traintest(Xtr,[],opt_tmp); 00522 GurlsOptionsList *kernel = predKernelTask.execute(*Xtr, empty, *opt_tmp); 00523 00524 gMat2D<T> &predkernel_K = kernel->getOptValue<OptMatrix<gMat2D<T> > >("K"); 00525 00526 // Kty(i_init:i_end,:) = kernel_col.K'*y; 00527 T* Kty_sub = new T[nindices*t]; 00528 dot(predkernel_K.getData(), ytr->getData(), Kty_sub, ntr, nindices, ntr, t, nindices, t, CblasTrans, CblasNoTrans, CblasColMajor); 00529 for(unsigned long i=0; i< t; ++i) 00530 copy(Kty+i_init+(i*guesses_end), Kty_sub+(i*nindices), nindices); 00531 00532 delete [] Kty_sub; 00533 00534 // KtK(i_init:i_end,i_init:i_end) = kernel_col.K'*kernel_col.K; 00535 T* KtK_sub = new T[nindices*nindices]; 00536 00537 dot(predkernel_K.getData(), predkernel_K.getData(), KtK_sub, ntr, nindices, ntr, nindices, nindices, nindices, CblasTrans, CblasNoTrans, CblasColMajor); 00538 for(unsigned long i=0; i< nindices; ++i) 00539 copy(KtK+i_init+((i_init+i)*guesses_end), KtK_sub+(i*nindices), nindices); 00540 00541 delete[] KtK_sub; 00542 00543 00544 // if guesses_c>1 00545 if(it != guesses.begin()) 00546 { 00547 // KtKcol = zeros((i_init-1),i_end-i_init+1); 00548 T *KtKcol = new T[i_init*nindices]; 00549 set(KtKcol, (T)0.0, i_init*nindices); 00550 00551 00552 const T salpha = (T)(-1.0/pow(sigma, 2)); 00553 const T one = (T) 1.0; 00554 00555 T *kernel_old = new T[i_init]; 00556 00557 const T *Xtr_it = Xtr->getData(); 00558 T *K_it = predkernel_K.getData(); 00559 00560 // for l=1:ntot 00561 for(unsigned long l = 0; l< ntr; ++l, ++Xtr_it, ++K_it) 00562 { 00563 // opt_tmp.rls.X = Xsub(1:(i_init-1),:); 00564 // kernel_old = predkernel_traintest(X(l,:),[],opt_tmp); 00565 distance_transposed_vm(Xtr_it, Xsub, d, guesses_end, kernel_old, i_init, ntr); 00566 scal(i_init, salpha, kernel_old, 1); 00567 exp(kernel_old, i_init); 00568 00569 // KtKcol = KtKcol + kernel_old.K'*kernel_col.K(l,:); 00570 gemv(CblasNoTrans, i_init, 1, one, kernel_old, i_init, K_it, ntr, one, KtKcol, 1); // 1 i_init 1 nindices i_init nindices 00571 } 00572 00573 delete [] kernel_old; 00574 00575 00576 // KtK(1:(i_init-1),i_init:i_end) = KtKcol; 00577 // KtK(i_init:i_end,1:(i_init-1)) = KtKcol'; 00578 for(unsigned long j=0; j<nindices; ++j) 00579 { 00580 copy(KtK+(guesses_end*(i_init+j)), KtKcol+(i_init*j), i_init); 00581 copy(KtK+i_init+j, KtKcol+(i_init*j), i_init, guesses_end, 1); 00582 } 00583 00584 delete [] KtKcol; 00585 } 00586 00587 delete kernel; 00588 00589 00590 // alpha = pinv(KtK(1:i_end,1:i_end))*(Kty(1:i_end,:)); 00591 00592 const unsigned long ii = i+1; 00593 00594 KtK_sub = new T[ ii*ii]; 00595 for(T *K_it = KtK, *Ks_it = KtK_sub, *const K_end = K_it+(guesses_end*ii); K_it != K_end; K_it+=guesses_end, Ks_it+=ii) 00596 copy(Ks_it, K_it, ii); 00597 00598 int r, c; 00599 T *pinv_K = pinv(KtK_sub, ii, ii, r, c); 00600 delete [] KtK_sub; 00601 00602 Kty_sub = new T[ii*t]; 00603 for(T *K_it = Kty, *Ks_it = Kty_sub, *const K_end = K_it+(guesses_end*t); K_it != K_end; K_it+=guesses_end, Ks_it+=ii) 00604 copy(Ks_it, K_it, ii); 00605 00606 00607 dot(pinv_K, Kty_sub, alpha, ii, ii, ii, t, ii, t, CblasNoTrans, CblasNoTrans, CblasColMajor); 00608 00609 delete [] Kty_sub; 00610 delete [] pinv_K; 00611 00612 00613 tmp_optimizer->removeOpt("X"); 00614 00615 // Xsub(i_init:i_end,:) = Xnew; 00616 for(T* Xsub_it = Xsub+i_init, *Xsub_end = Xsub_it+(guesses_end*d), *Xnew_it = Xnew->getData(); Xsub_it != Xsub_end; Xsub_it+=guesses_end, Xnew_it+=nindices) 00617 copy(Xsub_it, Xnew_it, nindices); 00618 00619 delete Xnew; 00620 00621 // i_init = i_end+1; 00622 i_init = i+1; 00623 00624 end = boost::posix_time::microsec_clock::local_time(); 00625 diff = end-begin; 00626 00627 *times_it = static_cast<unsigned long>(diff.total_milliseconds()); 00628 ++times_it; 00629 00630 ++guesses_mat_it; 00631 } 00632 00633 00634 delete [] indices; 00635 delete [] KtK; 00636 delete [] Kty; 00637 00638 delete opt_tmp; 00639 00640 00641 // vout.X = Xsub(1:i_end,:); 00642 paramsel->addOpt("X", new OptMatrix<gMat2D<T> >(*Xsub_mat)); 00643 00644 // vout.C = alpha; 00645 paramsel->addOpt("C", new OptMatrix<gMat2D<T> >(*alpha_mat)); 00646 00647 // vout.guesses = guesses; 00648 paramsel->addOpt("guesses", new OptMatrix<gMat2D<unsigned long> >(*guesses_mat)); 00649 00650 } 00651 00652 00653 template <typename T> 00654 gMat2D<T>* NystromWrapper<T>::eval(const gMat2D<T> &X) 00655 { 00656 GurlsOptionsList *opt = this->opt; 00657 const gMat2D<T> &alpha_mat = opt->getOptValue<OptMatrix<gMat2D<T> > >("paramsel.C"); 00658 const gMat2D<T> &X_mat = opt->getOptValue<OptMatrix<gMat2D<T> > >("paramsel.X"); 00659 00660 00661 const T *const alpha = alpha_mat.getData(); 00662 00663 const unsigned long n = X.rows(); 00664 const unsigned long t = alpha_mat.cols(); 00665 const unsigned long n_nystrom = X_mat.rows(); 00666 00667 PredKernelTrainTest<T> predKernelTask; 00668 00669 gMat2D<T> empty; 00670 00671 00672 GurlsOptionsList* opt_tmp = new GurlsOptionsList("tmp"); 00673 GurlsOptionsList* tmp_kernel = new GurlsOptionsList("kernel"); 00674 GurlsOptionsList* tmp_paramsel = new GurlsOptionsList("paramsel"); 00675 GurlsOptionsList* tmp_optimizer = new GurlsOptionsList("optimizer"); 00676 00677 opt_tmp->addOpt("kernel", tmp_kernel); 00678 opt_tmp->addOpt("paramsel", tmp_paramsel); 00679 opt_tmp->addOpt("optimizer", tmp_optimizer); 00680 00681 tmp_kernel->addOpt("type", opt->getOptAsString("kernel.type")); 00682 tmp_paramsel->addOpt("sigma", new OptNumber(opt->getOptAsNumber("paramsel.sigma"))); 00683 tmp_optimizer->addOpt("X", opt->getOpt("paramsel.X")); 00684 00685 gMat2D<T> *y = new gMat2D<T>(n, t); 00686 00687 GurlsOptionsList *predKernel = predKernelTask.execute(X, empty, *opt_tmp); 00688 const gMat2D<T> &predKernel_K = predKernel->getOptValue<OptMatrix<gMat2D<T> > >("K"); 00689 00690 dot(predKernel_K.getData(), alpha, y->getData(), n, n_nystrom, n_nystrom, t, n, t, CblasNoTrans, CblasNoTrans, CblasColMajor); 00691 00692 tmp_optimizer->removeOpt("X", false); 00693 00694 delete opt_tmp; 00695 delete predKernel; 00696 00697 return y; 00698 } 00699 00700 template <typename T> 00701 gMat2D<T>* NystromWrapper<T>::eval_largescale(const gMat2D<T> &X) 00702 { 00703 GurlsOptionsList *opt = this->opt; 00704 const gMat2D<T> &alpha_mat = opt->getOptValue<OptMatrix<gMat2D<T> > >("paramsel.alpha"); 00705 const gMat2D<T> &X_mat = opt->getOptValue<OptMatrix<gMat2D<T> > >("paramsel.X"); 00706 const T *const alpha = alpha_mat.getData(); 00707 00708 const unsigned long n = X.rows(); 00709 const unsigned long d = X.cols(); 00710 const unsigned long t = alpha_mat.cols(); 00711 const unsigned long n_nystrom = X_mat.rows(); 00712 00713 gMat2D<T> Xi_mat(1, d); 00714 T* yi = new T[t]; 00715 T* const Xi = Xi_mat.getData(); 00716 00717 gMat2D<T> *y_mat = new gMat2D<T>(n, t); 00718 T* y_it = y_mat->getData(); 00719 00720 GurlsOptionsList* opt_tmp = new GurlsOptionsList("tmp"); 00721 GurlsOptionsList* tmp_kernel = new GurlsOptionsList("kernel"); 00722 GurlsOptionsList* tmp_paramsel = new GurlsOptionsList("paramsel"); 00723 GurlsOptionsList* tmp_optimizer = new GurlsOptionsList("optimizer"); 00724 00725 opt_tmp->addOpt("kernel", tmp_kernel); 00726 opt_tmp->addOpt("paramsel", tmp_paramsel); 00727 opt_tmp->addOpt("optimizer", tmp_optimizer); 00728 00729 tmp_kernel->addOpt("type", opt->getOptAsString("kernel.type")); 00730 tmp_paramsel->addOpt("sigma", new OptNumber(opt->getOptAsNumber("sigma"))); 00731 tmp_optimizer->addOpt("X", opt->getOpt("paramsel.X")); 00732 00733 00734 PredKernelTrainTest<T> predKernelTask; 00735 const gMat2D<T> empty; 00736 00737 for(int i=0; i<n; ++i, ++y_it) 00738 { 00739 getRow(X.getData(), n, d, i, Xi); 00740 00741 GurlsOptionsList *predKernel = predKernelTask.execute(Xi_mat, empty, *opt_tmp); 00742 const gMat2D<T> &predKernel_K = predKernel->getOptValue<OptMatrix<gMat2D<T> > >("K"); 00743 00744 dot(predKernel_K.getData(), alpha, yi, 1, n_nystrom, n_nystrom, t, 1, t, CblasNoTrans, CblasNoTrans, CblasColMajor); 00745 copy(y_it, yi, t, n, 1); 00746 00747 delete predKernel; 00748 } 00749 00750 tmp_optimizer->removeOpt("X", false); 00751 delete opt_tmp; 00752 delete [] yi; 00753 00754 return y_mat; 00755 } 00756 00757 template <typename T> 00758 void NystromWrapper<T>::setParam(double value) 00759 { 00760 this->setNparams(1); 00761 00762 if(this->opt->hasOpt("n_nystrom")) 00763 this->opt->template getOptValue<OptNumber>("n_nystrom") = value; 00764 else 00765 this->opt->addOpt("n_nystrom", new OptNumber(value)); 00766 } 00767 00768 //template <typename T> 00769 //void NystromWrapper<T>::rescale(gMat2D<T> &y) 00770 //{ 00771 // const unsigned long n = y.rows(); 00772 // const unsigned long t = y.cols(); 00773 00774 // T* yt = new T[y.getSize()]; 00775 00776 // transpose(y.getData(), n, t, yt); 00777 00778 00779 // //unsigned long counts[2] = {0, 0}; 00780 // unsigned long *counts = new unsigned long [t]; 00781 // set(counts, 0ul, t); 00782 00783 // unsigned long *maxIndices = new unsigned long [n]; 00784 // unsigned long *m_it = maxIndices; 00785 00786 00787 // T *it = yt; 00788 // for(unsigned long i=0; i<n; ++i, it+=t) 00789 // { 00790 // unsigned long mindex = std::max_element(it, it+t)-it; 00791 00792 // *m_it++ = mindex; 00793 // ++counts[mindex]; 00794 // } 00795 00796 // delete [] yt; 00797 00798 // unsigned long *coeffs = new unsigned long [t]; 00799 // set(coeffs, 0ul, t); 00800 // for(unsigned long i=0; i<t; ++i) 00801 // { 00802 // for(unsigned long j=0; j<t; ++j) 00803 // if(i!=j) 00804 // coeffs[i] += counts[j]; 00805 // } 00806 00807 // it = y.getData(); 00808 // m_it = maxIndices; 00809 00810 // for(unsigned long i=0; i<n; ++i, ++it, ++m_it) 00812 // scal(t, (T)(coeffs[*m_it]), it, n); 00813 00814 00815 // delete [] counts; 00816 // delete [] coeffs; 00817 00818 00819 // delete [] maxIndices; 00820 00821 //} 00822 00823 template <typename T> 00824 unsigned long* NystromWrapper<T>::getIndices(const gMat2D<T>&y, const unsigned long n, const unsigned long t, const unsigned long n_nystrom, unsigned long &length) 00825 { 00826 unsigned long *indices = new unsigned long[n]; 00827 randperm(n, indices, true, 0); 00828 00829 length = n; 00830 return indices; 00831 } 00832 00833 }