/** * @file testKernelOptimization.cpp * @brief test kernel optimization * @author Erik Rodner * @date 12/08/2009 */ #include #include "core/basics/Config.h" #include "vislearning/cbaselib/LabeledSet.h" #include "vislearning/math/kernels/KernelExp.h" #include "vislearning/regression/gpregression/GPRegressionOptimizationProblem.h" using namespace std; using namespace OBJREC; using namespace NICE; void testOverallDeriv ( KernelData *kernelData, const VVector & y, ParameterizedKernel & kernelFunction, const Vector & iparameters, double step, double interval ) { double a_max = 0.0; bool firstIteration = true; double oldObj = 0.0; GPRegressionOptimizationProblem gp_problem ( kernelData, y, &kernelFunction, true, NULL ); for ( double s = -interval ; s <= interval ; s+=step ) { Vector parameters ( iparameters ); parameters[0] += s; gp_problem.setParameters( parameters ); double obj = gp_problem.computeObjective ( ); Vector gradient; gp_problem.computeGradient( gradient ); double deriv = gradient[0]; if ( ! firstIteration ) { double derivApprox = ( obj - oldObj ) / step; double a = fabs(deriv - derivApprox); if ( a > a_max ) a_max = a; cerr << "EVAL: " << parameters[0] << " objective " << obj << " D(closedform) " << deriv << " D(approximated) " << derivApprox << endl; } firstIteration = false; oldObj = obj; } cerr << "Maximum difference between real derivative and approximation: " << a_max << endl; } void testKernelDeriv ( KernelData *kernelData, ParameterizedKernel & kernelFunction, const Vector & iparameters, double step ) { double oldKernelSum = 0.0; bool firstIteration = true; double a_max = 0.0; for ( double s = -1.0 ; s <= 1.0 ; s+=step ) { Vector parameters ( iparameters ); parameters[0] += s; //cerr << parameters << endl; kernelFunction.setParameters ( parameters ); kernelFunction.updateKernelData ( kernelData ); Matrix jacobiMatrix; kernelFunction.getKernelJacobi ( 0, parameters, kernelData, jacobiMatrix ); const Matrix & kernelMatrix = kernelData->getKernelMatrix(); double kernelSum = 0.0; double derivSum = 0.0; for ( uint i = 0 ; i < kernelMatrix.rows() ; i++ ) for ( uint j = 0 ; j < kernelMatrix.cols(); j++ ) { kernelSum += kernelMatrix(i,j); derivSum += jacobiMatrix(i,j); } kernelSum /= kernelMatrix.rows() * kernelMatrix.cols(); derivSum /= kernelMatrix.rows() * kernelMatrix.cols(); if ( ! firstIteration ) { double derivApprox = ( kernelSum - oldKernelSum ) / step; double a = fabs(derivSum - derivApprox); if ( a > a_max ) a_max = a; //cerr << "K " << kernelSum << " D " << derivSum << " Diff " << ( kernelSum - oldKernelSum ) / step << endl; } firstIteration = false; oldKernelSum = kernelSum; } cerr << "Maximum difference between real derivative and approximation: " << a_max << endl; } /** test kernel optimization */ int main (int argc, char **argv) { #ifndef __clang__ #ifndef __llvm__ std::set_terminate(__gnu_cxx::__verbose_terminate_handler); #endif #endif Config conf ( argc, argv ); KernelExp kernelFunction ( conf.gD("KCGPRegression", "rbf_gamma", -2.5), 0.0 ); LabeledSetVector train; string setfn = conf.gS("main", "train"); int format = conf.gI("main", "format", 2 ); train.read ( setfn, format ); VVector trainUnlabeled; Vector y; train.getFlatRepresentation ( trainUnlabeled, y ); KernelData kernelData ( &conf ); for ( VVector::iterator i = trainUnlabeled.begin(); i != trainUnlabeled.end(); i++ ) { Vector & v = *i; v.normL2(); } kernelFunction.calcKernelData ( trainUnlabeled, &kernelData ); Vector iparameters ( 2 ); iparameters[0] = conf.gD("KCGPRegression", "rbf_gamma", -2.5); iparameters[1] = 0.0; double step = conf.gD("main", "step", 0.01 ); double interval = conf.gD("main", "interval", 1.0 ); bool testkernelderiv = conf.gB("main", "testkernelderiv", true ); if ( testkernelderiv ) testKernelDeriv ( &kernelData, kernelFunction, iparameters, step ); else { VVector yy; if ( (y.Max() == 1) && (y.Min() == 0) ) { cerr << "Binary classification problem" << endl; Vector by ( y.size() ); for ( size_t j = 0 ; j < y.size() ; j++ ) by[j] = 2*y[j] - 1; yy.push_back (by); } else { int numClasses = y.Max() + 1; for ( size_t i = 0 ; i < numClasses ; i++ ) { Vector by ( y.size() ); for ( size_t j = 0 ; j < y.size() ; j++ ) if ( y[j] == i ) by[j] = 1; else by[j] = -1; yy.push_back(by); } } testOverallDeriv ( &kernelData, yy, kernelFunction, iparameters, step, interval ); } return 0; }