bool computeEfficiency2(efficiency::Efficiency_s2::Request &req, efficiency::Efficiency_s2::Response &res) { double effic_cte_weigth_smoothness, effic_cte_weigth_safety, effic_cte_weigth_directness; bool isOk = true; //ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b); //obtener constantes del servidor de constantes if (!ros::param::getCached("~/effic_cte_weigth_smoothness", effic_cte_weigth_smoothness)) { ROS_ERROR("Unable to retrieve smoothness weigth parameter"); isOk = false; } if (!ros::param::getCached("~/effic_cte_weigth_safety", effic_cte_weigth_safety)) { ROS_ERROR("Unable to retrieve safety weigth parameter"); isOk = false; } if (!ros::param::getCached("~/effic_cte_weigth_directness", effic_cte_weigth_directness)) { ROS_ERROR("Unable to retrieve directness weigth parameter"); isOk = false; } if (isOk) { //ROS_INFO("Weigth factors correct : (%f,%f,%f) ",effic_cte_weigth_smoothness, // effic_cte_weigth_safety, effic_cte_weigth_directness); printInputInfo(req); //BEEEF!!! if ((req.comand.x == 0.0) && (req.comand.y == 0.0)) { res.eta.Global = 0.0; res.eta.Safety = 0.0; res.eta.Directness = 0.0; res.eta.Smoothness = 0.0; } else { // EVALUACION EFICIENCIA. 3 FACTORES //---------------------------------------------------------------------- // smoothness FACTOR //---------------------------------------------------------------------- // In general is better to keep trayectory as soft as possible. Robot heading // is always 0º so as near alfa_dir is to 0º better would be the eficiency isOk &= evalSmoothness(req.comand, &res.eta.Smoothness); //res.eta.Smoothness = evalSmoothness(req); //ROS_INFO("SM calculated: %f ",res.eta.Smoothness ); //---------------------------------------------------------------------- // DISTANCE FACTOR //---------------------------------------------------------------------- // It's not possible to measure distance factor, so it's measured minimizing angle // between target and actual comand angle direction. If this diference is near to 0 // we're going in the right direction and eficiency is better. isOk &= evalDirectness(req.comand, req.target, req.robotPos, &res.eta.Directness); //res.eta.Directness = evalDirectness(req); //ROS_INFO("DI calculated: %f ",res.eta.Directness); //---------------------------------------------------------------------- // SECURITY FACTOR //---------------------------------------------------------------------- // Obstacles that makes as moving from our trayectory are bad and decrease eficiency, so // they must be avoid. So as near it is the obstacle and as near from the heading direction (0º) // worse would be the eficiency. isOk &= evalSafety(req.comand, req.target, req.robotPos, req.obstacles, &res.eta.Safety); //res.eta.Safety = evalSafety(req); // ROS_INFO("SF calculated: %f ", res.eta.Safety); // Apply weigths and global efficiency calculation res.eta.Smoothness = res.eta.Smoothness * effic_cte_weigth_smoothness; res.eta.Directness = res.eta.Directness* effic_cte_weigth_directness; res.eta.Safety = res.eta.Safety * effic_cte_weigth_safety; res.eta.Global = res.eta.Smoothness + res.eta.Directness + res.eta.Safety; res.eta.Global = res.eta.Global / (effic_cte_weigth_smoothness + effic_cte_weigth_safety + effic_cte_weigth_directness); //ROS_INFO("Glob eta: %f",res.eta.Global); } } if (isOk) printOutputInfo(res.eta); return isOk; }
void FilterBoostLearner::run(const nor_utils::Args& args) { // load the arguments this->getArgs(args); time_t startTime, currentTime; time(&startTime); // get the registered weak learner (type from name) BaseLearner* pWeakHypothesisSource = BaseLearner::RegisteredLearners().getLearner(_baseLearnerName); // initialize learning options; normally it's done in the strong loop // also, here we do it for Product learners, so input data can be created pWeakHypothesisSource->initLearningOptions(args); BaseLearner* pConstantWeakHypothesisSource = BaseLearner::RegisteredLearners().getLearner("ConstantLearner"); // get the training input data, and load it InputData* pTrainingData = pWeakHypothesisSource->createInputData(); pTrainingData->initOptions(args); pTrainingData->load(_trainFileName, IT_TRAIN, _verbose); const int numClasses = pTrainingData->getNumClasses(); const int numExamples = pTrainingData->getNumExamples(); //initialize the margins variable _margins.resize( numExamples ); for( int i=0; i<numExamples; i++ ) { _margins[i].resize( numClasses ); fill( _margins[i].begin(), _margins[i].end(), 0.0 ); } // get the testing input data, and load it InputData* pTestData = NULL; if ( !_testFileName.empty() ) { pTestData = pWeakHypothesisSource->createInputData(); pTestData->initOptions(args); pTestData->load(_testFileName, IT_TEST, _verbose); } // The output information object OutputInfo* pOutInfo = NULL; if ( !_outputInfoFile.empty() ) { // Baseline: constant classifier - goes into 0th iteration BaseLearner* pConstantWeakHypothesis = pConstantWeakHypothesisSource->create() ; pConstantWeakHypothesis->initLearningOptions(args); pConstantWeakHypothesis->setTrainingData(pTrainingData); AlphaReal constantEnergy = pConstantWeakHypothesis->run(); pOutInfo = new OutputInfo(args); pOutInfo->initialize(pTrainingData); updateMargins( pTrainingData, pConstantWeakHypothesis ); if (pTestData) pOutInfo->initialize(pTestData); pOutInfo->outputHeader(pTrainingData->getClassMap() ); pOutInfo->outputIteration(-1); pOutInfo->outputCustom(pTrainingData, pConstantWeakHypothesis); if (pTestData) { pOutInfo->separator(); pOutInfo->outputCustom(pTestData, pConstantWeakHypothesis); } pOutInfo->outputCurrentTime(); pOutInfo->endLine(); pOutInfo->initialize(pTrainingData); if (pTestData) pOutInfo->initialize(pTestData); } // reload the previously found weak learners if -resume is set. // otherwise just return 0 int startingIteration = resumeWeakLearners(pTrainingData); Serialization ss(_shypFileName, _isShypCompressed ); ss.writeHeader(_baseLearnerName); // this must go after resumeProcess has been called // perform the resuming if necessary. If not it will just return resumeProcess(ss, pTrainingData, pTestData, pOutInfo); if (_verbose == 1) cout << "Learning in progress..." << endl; /////////////////////////////////////////////////////////////////////// // Starting the AdaBoost main loop /////////////////////////////////////////////////////////////////////// for (int t = startingIteration; t < _numIterations; ++t) { if (_verbose > 1) cout << "------- WORKING ON ITERATION " << (t+1) << " -------" << endl; // create the weak learner BaseLearner* pWeakHypothesis; BaseLearner* pConstantWeakHypothesis; pWeakHypothesis = pWeakHypothesisSource->create(); pWeakHypothesis->initLearningOptions(args); //pTrainingData->clearIndexSet(); pWeakHypothesis->setTrainingData(pTrainingData); AlphaReal edge, energy=0.0; // create the constant learner pConstantWeakHypothesis = pConstantWeakHypothesisSource->create() ; pConstantWeakHypothesis->initLearningOptions(args); pConstantWeakHypothesis->setTrainingData(pTrainingData); AlphaReal constantEdge = -numeric_limits<AlphaReal>::max(); int currentNumberOfUsedData = static_cast<int>(_Cn * log(t+3.0)); if ( _onlineWeakLearning ) { //check whether the weak learner is a ScalarLeaerner try { StochasticLearner* pStochasticLearner = dynamic_cast<StochasticLearner*>(pWeakHypothesis); StochasticLearner* pStochasticConstantWeakHypothesis = dynamic_cast<StochasticLearner*> (pConstantWeakHypothesis); pStochasticLearner->initLearning(); pStochasticConstantWeakHypothesis->initLearning(); if (_verbose>1) cout << "Number of random instances: \t" << currentNumberOfUsedData << endl; // set the weights setWeightToMargins(pTrainingData); //learning for (int i=0; i<currentNumberOfUsedData; ++i ) { int randomIndex = (rand() % pTrainingData->getNumExamples()); //int randomIndex = getRandomIndex(); pStochasticLearner->update(randomIndex); pStochasticConstantWeakHypothesis->update(randomIndex); } pStochasticLearner->finishLearning(); pStochasticConstantWeakHypothesis->finishLearning(); } catch (bad_cast& e) { cerr << "The weak learner must be a StochasticLearner!!!" << endl; exit(-1); } } else { filter( pTrainingData, currentNumberOfUsedData ); if ( pTrainingData->getNumExamples() < 2 ) { filter( pTrainingData, currentNumberOfUsedData, false ); } if (_verbose > 1) { cout << "--> Size of training data = " << pTrainingData->getNumExamples() << endl; } energy = pWeakHypothesis->run(); pConstantWeakHypothesis->run(); } //estimate edge filter( pTrainingData, currentNumberOfUsedData, false ); edge = pWeakHypothesis->getEdge(true) / 2.0; constantEdge = pConstantWeakHypothesis->getEdge() / 2.0; if ( constantEdge > edge ) { delete pWeakHypothesis; pWeakHypothesis = pConstantWeakHypothesis; edge = constantEdge; } else { delete pConstantWeakHypothesis; } // calculate alpha AlphaReal alpha = 0.0; alpha = 0.5 * log( ( 1 + edge ) / ( 1 - edge ) ); pWeakHypothesis->setAlpha( alpha ); _sumAlpha += alpha; if (_verbose > 1) cout << "Weak learner: " << pWeakHypothesis->getName()<< endl; // Output the step-by-step information pTrainingData->clearIndexSet(); printOutputInfo(pOutInfo, t, pTrainingData, pTestData, pWeakHypothesis); // Updates the weights and returns the edge //AlphaReal gamma = updateWeights(pTrainingData, pWeakHypothesis); if (_verbose > 1) { cout << setprecision(5) << "--> Alpha = " << pWeakHypothesis->getAlpha() << endl << "--> Edge = " << edge << endl << "--> Energy = " << energy << endl // << "--> ConstantEnergy = " << constantEnergy << endl // << "--> difference = " << (energy - constantEnergy) << endl ; } // update the margins //saveMargins(); updateMargins( pTrainingData, pWeakHypothesis ); // append the current weak learner to strong hypothesis file, // that is, serialize it. ss.appendHypothesis(t, pWeakHypothesis); // Add it to the internal list of weak hypotheses _foundHypotheses.push_back(pWeakHypothesis); // check if the time limit has been reached if (_maxTime > 0) { time( ¤tTime ); float diff = difftime(currentTime, startTime); // difftime is in seconds diff /= 60; // = minutes if (diff > _maxTime) { if (_verbose > 0) cout << "Time limit of " << _maxTime << " minutes has been reached!" << endl; break; } } // check for maxtime delete pWeakHypothesis; } // loop on iterations ///////////////////////////////////////////////////////// // write the footer of the strong hypothesis file ss.writeFooter(); // Free the two input data objects if (pTrainingData) delete pTrainingData; if (pTestData) delete pTestData; if (pOutInfo) delete pOutInfo; if (_verbose > 0) cout << "Learning completed." << endl; }
void FilterBoostLearner::resumeProcess(Serialization& ss, InputData* pTrainingData, InputData* pTestData, OutputInfo* pOutInfo) { if (_resumeShypFileName.empty()) return; if (_verbose > 0) cout << "Resuming up to iteration " << _foundHypotheses.size() - 1 << ": 0%." << flush; vector<BaseLearner*>::iterator it; int t; // rebuild the new strong hypothesis file for (it = _foundHypotheses.begin(), t = 0; it != _foundHypotheses.end(); ++it, ++t) { BaseLearner* pWeakHypothesis = *it; // append the current weak learner to strong hypothesis file, ss.appendHypothesis(t, pWeakHypothesis); } const int numIters = static_cast<int>(_foundHypotheses.size()); const int step = numIters < 5 ? 1 : numIters / 5; // simulate the AdaBoost algorithm for the weak learners already found for (it = _foundHypotheses.begin(), t = 0; it != _foundHypotheses.end(); ++it, ++t) { BaseLearner* pWeakHypothesis = *it; // Output the step-by-step information printOutputInfo(pOutInfo, t, pTrainingData, pTestData, pWeakHypothesis); // Updates the weights and returns the edge updateMargins(pTrainingData, pWeakHypothesis); //updateFxs( pTrainingData, pWeakHypothesis ); if (_verbose > 1 && (t + 1) % step == 0) { float progress = static_cast<float>(t) / static_cast<float>(numIters) * 100.0; cout << "." << setprecision(2) << progress << "%." << flush; } // If gamma <= theta there is something really wrong. /* if (gamma <= _theta) { cerr << "ERROR!" << setprecision(4) << endl << "At iteration <" << t << ">, edge smaller than the edge offset (theta). Something must be wrong!" << endl << "[Edge: " << gamma << " < Offset: " << _theta << "]" << endl << "Is the data file the same one used during the original training?" << endl; // exit(1); } */ } // loop on iterations if (_verbose > 0) cout << "Done!" << endl; }
void FilterBoostLearner::run(const nor_utils::Args& args) { // load the arguments this->getArgs(args); time_t startTime, currentTime; time(&startTime); // get the registered weak learner (type from name) BaseLearner* pWeakHypothesisSource = BaseLearner::RegisteredLearners().getLearner(_baseLearnerName); // initialize learning options; normally it's done in the strong loop // also, here we do it for Product learners, so input data can be created pWeakHypothesisSource->initLearningOptions(args); BaseLearner* pConstantWeakHypothesisSource = BaseLearner::RegisteredLearners().getLearner("ConstantLearner"); // get the training input data, and load it InputData* pTrainingData = pWeakHypothesisSource->createInputData(); pTrainingData->initOptions(args); pTrainingData->load(_trainFileName, IT_TRAIN, _verbose); const int numClasses = pTrainingData->getNumClasses(); const int numExamples = pTrainingData->getNumExamples(); //initialize the margins variable _margins.resize( numExamples ); for( int i=0; i<numExamples; i++ ) { _margins[i].resize( numClasses ); fill( _margins[i].begin(), _margins[i].end(), 0.0 ); } // get the testing input data, and load it InputData* pTestData = NULL; if ( !_testFileName.empty() ) { pTestData = pWeakHypothesisSource->createInputData(); pTestData->initOptions(args); pTestData->load(_testFileName, IT_TEST, _verbose); } // The output information object OutputInfo* pOutInfo = NULL; if ( !_outputInfoFile.empty() ) { // Baseline: constant classifier - goes into 0th iteration BaseLearner* pConstantWeakHypothesis = pConstantWeakHypothesisSource->create() ; pConstantWeakHypothesis->initLearningOptions(args); pConstantWeakHypothesis->setTrainingData(pTrainingData); float constantEnergy = pConstantWeakHypothesis->run(); pOutInfo = new OutputInfo(_outputInfoFile); pOutInfo->initialize(pTrainingData); updateMargins( pTrainingData, pConstantWeakHypothesis ); if (pTestData) pOutInfo->initialize(pTestData); pOutInfo->outputHeader(); pOutInfo->outputIteration(-1); pOutInfo->outputError(pTrainingData, pConstantWeakHypothesis); if (pTestData) pOutInfo->outputError(pTestData, pConstantWeakHypothesis); /* pOutInfo->outputMargins(pTrainingData, pConstantWeakHypothesis); pOutInfo->outputEdge(pTrainingData, pConstantWeakHypothesis); if (pTestData) pOutInfo->outputMargins(pTestData, pConstantWeakHypothesis); pOutInfo->outputMAE(pTrainingData); if (pTestData) pOutInfo->outputMAE(pTestData); */ pOutInfo->outputCurrentTime(); pOutInfo->endLine(); pOutInfo->initialize(pTrainingData); if (pTestData) pOutInfo->initialize(pTestData); } // reload the previously found weak learners if -resume is set. // otherwise just return 0 int startingIteration = resumeWeakLearners(pTrainingData); Serialization ss(_shypFileName, _isShypCompressed ); ss.writeHeader(_baseLearnerName); // this must go after resumeProcess has been called // perform the resuming if necessary. If not it will just return resumeProcess(ss, pTrainingData, pTestData, pOutInfo); if (_verbose == 1) cout << "Learning in progress..." << endl; /////////////////////////////////////////////////////////////////////// // Starting the AdaBoost main loop /////////////////////////////////////////////////////////////////////// for (int t = startingIteration; t < _numIterations; ++t) { if (_verbose > 1) cout << "------- WORKING ON ITERATION " << (t+1) << " -------" << endl; filter( pTrainingData, (int)(_Cn * log(t+2.0)) ); if ( pTrainingData->getNumExamples() < 2 ) { filter( pTrainingData, (int)(_Cn * log(t+2.0)), false ); } if (_verbose > 1) { cout << "--> Size of training data = " << pTrainingData->getNumExamples() << endl; } BaseLearner* pWeakHypothesis = pWeakHypothesisSource->create(); pWeakHypothesis->initLearningOptions(args); //pTrainingData->clearIndexSet(); pWeakHypothesis->setTrainingData(pTrainingData); float energy = pWeakHypothesis->run(); BaseLearner* pConstantWeakHypothesis; if (_withConstantLearner) // check constant learner if user wants it { pConstantWeakHypothesis = pConstantWeakHypothesisSource->create() ; pConstantWeakHypothesis->initLearningOptions(args); pConstantWeakHypothesis->setTrainingData(pTrainingData); float constantEnergy = pConstantWeakHypothesis->run(); } //estimate edge filter( pTrainingData, (int)(_Cn * log(t+2.0)), false ); float edge = pWeakHypothesis->getEdge() / 2.0; if (_withConstantLearner) // check constant learner if user wants it { float constantEdge = pConstantWeakHypothesis->getEdge() / 2.0; if ( constantEdge > edge ) { delete pWeakHypothesis; pWeakHypothesis = pConstantWeakHypothesis; edge = constantEdge; } else { delete pConstantWeakHypothesis; } } // calculate alpha float alpha = 0.0; alpha = 0.5 * log( ( 0.5 + edge ) / ( 0.5 - edge ) ); pWeakHypothesis->setAlpha( alpha ); if (_verbose > 1) cout << "Weak learner: " << pWeakHypothesis->getName()<< endl; // Output the step-by-step information pTrainingData->clearIndexSet(); printOutputInfo(pOutInfo, t, pTrainingData, pTestData, pWeakHypothesis); // Updates the weights and returns the edge float gamma = updateWeights(pTrainingData, pWeakHypothesis); if (_verbose > 1) { cout << setprecision(5) << "--> Alpha = " << pWeakHypothesis->getAlpha() << endl << "--> Edge = " << gamma << endl << "--> Energy = " << energy << endl // << "--> ConstantEnergy = " << constantEnergy << endl // << "--> difference = " << (energy - constantEnergy) << endl ; } // update the margins updateMargins( pTrainingData, pWeakHypothesis ); // append the current weak learner to strong hypothesis file, // that is, serialize it. ss.appendHypothesis(t, pWeakHypothesis); // Add it to the internal list of weak hypotheses _foundHypotheses.push_back(pWeakHypothesis); // check if the time limit has been reached if (_maxTime > 0) { time( ¤tTime ); float diff = difftime(currentTime, startTime); // difftime is in seconds diff /= 60; // = minutes if (diff > _maxTime) { if (_verbose > 0) cout << "Time limit of " << _maxTime << " minutes has been reached!" << endl; break; } } // check for maxtime delete pWeakHypothesis; } // loop on iterations ///////////////////////////////////////////////////////// // write the footer of the strong hypothesis file ss.writeFooter(); // Free the two input data objects if (pTrainingData) delete pTrainingData; if (pTestData) delete pTestData; if (pOutInfo) delete pOutInfo; if (_verbose > 0) cout << "Learning completed." << endl; }
void AdaBoostMHLearner::run(const nor_utils::Args& args) { // load the arguments this->getArgs(args); // get the registered weak learner (type from name) BaseLearner* pWeakHypothesisSource = BaseLearner::RegisteredLearners().getLearner(_baseLearnerName); // initialize learning options; normally it's done in the strong loop // also, here we do it for Product learners, so input data can be created pWeakHypothesisSource->initLearningOptions(args); BaseLearner* pConstantWeakHypothesisSource = BaseLearner::RegisteredLearners().getLearner("ConstantLearner"); // get the training input data, and load it InputData* pTrainingData = pWeakHypothesisSource->createInputData(); pTrainingData->initOptions(args); pTrainingData->load(_trainFileName, IT_TRAIN, _verbose); // get the testing input data, and load it InputData* pTestData = NULL; if ( !_testFileName.empty() ) { pTestData = pWeakHypothesisSource->createInputData(); pTestData->initOptions(args); pTestData->load(_testFileName, IT_TEST, _verbose); } // The output information object OutputInfo* pOutInfo = NULL; if ( !_outputInfoFile.empty() ) { // Baseline: constant classifier - goes into 0th iteration BaseLearner* pConstantWeakHypothesis = pConstantWeakHypothesisSource->create() ; pConstantWeakHypothesis->initLearningOptions(args); pConstantWeakHypothesis->setTrainingData(pTrainingData); AlphaReal constantEnergy = pConstantWeakHypothesis->run(); //pOutInfo = new OutputInfo(_outputInfoFile); pOutInfo = new OutputInfo(args); pOutInfo->initialize(pTrainingData); if (pTestData) pOutInfo->initialize(pTestData); pOutInfo->outputHeader(pTrainingData->getClassMap()); pOutInfo->outputIteration(-1); pOutInfo->outputCustom(pTrainingData, pConstantWeakHypothesis); if (pTestData != NULL) { pOutInfo->separator(); pOutInfo->outputCustom(pTestData, pConstantWeakHypothesis); } pOutInfo->outputCurrentTime(); pOutInfo->endLine(); pOutInfo->initialize(pTrainingData); if (pTestData) pOutInfo->initialize(pTestData); } //cout << "Before serialization" << endl; // reload the previously found weak learners if -resume is set. // otherwise just return 0 int startingIteration = resumeWeakLearners(pTrainingData); Serialization ss(_shypFileName, _isShypCompressed ); ss.writeHeader(_baseLearnerName); // this must go after resumeProcess has been called // perform the resuming if necessary. If not it will just return resumeProcess(ss, pTrainingData, pTestData, pOutInfo); if (_verbose == 1) cout << "Learning in progress..." << endl; //I put here the starting time, but it may take very long time to load the saved model time_t startTime, currentTime; time(&startTime); /////////////////////////////////////////////////////////////////////// // Starting the AdaBoost main loop /////////////////////////////////////////////////////////////////////// for (int t = startingIteration; t < _numIterations; ++t) { if (_verbose > 1) cout << "------- WORKING ON ITERATION " << (t+1) << " -------" << endl; BaseLearner* pWeakHypothesis = pWeakHypothesisSource->create(); pWeakHypothesis->initLearningOptions(args); //pTrainingData->clearIndexSet(); pWeakHypothesis->setTrainingData(pTrainingData); AlphaReal energy = pWeakHypothesis->run(); //float gamma = pWeakHypothesis->getEdge(); //cout << gamma << endl; if ( (_withConstantLearner) || ( energy != energy ) ) // check constant learner if user wants it (if energi is nan, then we chose constant learner { BaseLearner* pConstantWeakHypothesis = pConstantWeakHypothesisSource->create() ; pConstantWeakHypothesis->initLearningOptions(args); pConstantWeakHypothesis->setTrainingData(pTrainingData); AlphaReal constantEnergy = pConstantWeakHypothesis->run(); if ( (constantEnergy <= energy) || ( energy != energy ) ) { delete pWeakHypothesis; pWeakHypothesis = pConstantWeakHypothesis; } } if (_verbose > 1) cout << "Weak learner: " << pWeakHypothesis->getName()<< endl; // Output the step-by-step information printOutputInfo(pOutInfo, t, pTrainingData, pTestData, pWeakHypothesis); // Updates the weights and returns the edge AlphaReal gamma = updateWeights(pTrainingData, pWeakHypothesis); if (_verbose > 1) { cout << setprecision(5) << "--> Alpha = " << pWeakHypothesis->getAlpha() << endl << "--> Edge = " << gamma << endl << "--> Energy = " << energy << endl // << "--> ConstantEnergy = " << constantEnergy << endl // << "--> difference = " << (energy - constantEnergy) << endl ; } // If gamma <= theta the algorithm must stop. // If theta == 0 and gamma is 0, it means that the weak learner is no better than chance // and no further training is possible. if (gamma <= _theta) { if (_verbose > 0) { cout << "Can't train any further: edge = " << gamma << " (with and edge offset (theta)=" << _theta << ")" << endl; } // delete pWeakHypothesis; // break; } // append the current weak learner to strong hypothesis file, // that is, serialize it. ss.appendHypothesis(t, pWeakHypothesis); // Add it to the internal list of weak hypotheses _foundHypotheses.push_back(pWeakHypothesis); // check if the time limit has been reached if (_maxTime > 0) { time( ¤tTime ); float diff = difftime(currentTime, startTime); // difftime is in seconds diff /= 60; // = minutes if (diff > _maxTime) { if (_verbose > 0) cout << "Time limit of " << _maxTime << " minutes has been reached!" << endl; break; } } // check for maxtime delete pWeakHypothesis; } // loop on iterations ///////////////////////////////////////////////////////// // write the footer of the strong hypothesis file ss.writeFooter(); // write the weights of the instances if the name of weights file isn't empty printOutWeights( pTrainingData ); // Free the two input data objects if (pTrainingData) delete pTrainingData; if (pTestData) delete pTestData; if (pOutInfo) delete pOutInfo; if (_verbose > 0) cout << "Learning completed." << endl; }
void SoftCascadeLearner::run(const nor_utils::Args& args) { // load the arguments this->getArgs(args); //print cascade properties if (_verbose > 0) { cout << "[+] Softcascade parameters :" << endl << "\t --> target detection rate = " << _targetDetectionRate << endl << "\t --> alpha (exp param) = " << _alphaExponentialParameter << endl << "\t --> bootstrap rate = " << _bootstrapRate << endl << endl; } // get the registered weak learner (type from name) BaseLearner* pWeakHypothesisSource = BaseLearner::RegisteredLearners().getLearner(_baseLearnerName); // initialize learning options; normally it's done in the strong loop // also, here we do it for Product learners, so input data can be created pWeakHypothesisSource->initLearningOptions(args); // get the training input data, and load it InputData* pTrainingData = pWeakHypothesisSource->createInputData(); pTrainingData->initOptions(args); pTrainingData->load(_trainFileName, IT_TRAIN, 5); InputData* pBootstrapData = NULL; if (!_bootstrapFileName.empty()) { pBootstrapData = pWeakHypothesisSource->createInputData(); pBootstrapData->initOptions(args); pBootstrapData->load(_bootstrapFileName, IT_TRAIN, 5); } // get the testing input data, and load it InputData* pTestData = NULL; if ( !_testFileName.empty() ) { pTestData = pWeakHypothesisSource->createInputData(); pTestData->initOptions(args); pTestData->load(_testFileName, IT_TEST, 5); } Serialization ss(_shypFileName, false ); ss.writeHeader(_baseLearnerName); // outputHeader(); // The output information object OutputInfo* pOutInfo = NULL; if ( !_outputInfoFile.empty() ) { pOutInfo = new OutputInfo(args, true); pOutInfo->setOutputList("sca", &args); pOutInfo->initialize(pTrainingData); if (pTestData) pOutInfo->initialize(pTestData); pOutInfo->outputHeader(pTrainingData->getClassMap(), true, true, false); pOutInfo->outputUserHeader("thresh"); pOutInfo->headerEndLine(); } // ofstream trainPosteriorsFile; // ofstream testPosteriorsFile; const NameMap& namemap = pTrainingData->getClassMap(); _positiveLabelIndex = namemap.getIdxFromName(_positiveLabelName); // FIXME: output posteriors // OutputInfo* pTrainPosteriorsOut = NULL; // OutputInfo* pTestPosteriorsOut = NULL; // if (! _trainPosteriorsFileName.empty()) { // pTrainPosteriorsOut = new OutputInfo(_trainPosteriorsFileName, "pos", true); // pTrainPosteriorsOut->initialize(pTrainingData); // dynamic_cast<PosteriorsOutput*>( pTrainPosteriorsOut->getOutputInfoObject("pos") )->addClassIndex(_positiveLabelIndex ); // } // if (! _testPosteriorsFileName.empty() && !_testFileName.empty() ) { // pTestPosteriorsOut = new OutputInfo(_testPosteriorsFileName, "pos", true); // pTestPosteriorsOut->initialize(pTestData); // dynamic_cast<PosteriorsOutput*>( pTestPosteriorsOut->getOutputInfoObject("pos") )->addClassIndex(_positiveLabelIndex ); // } const int numExamples = pTrainingData->getNumExamples(); vector<BaseLearner*> inWeakHypotheses; if (_fullRun) { // TODO : the full training is implementet, testing is needed AdaBoostMHLearner* sHypothesis = new AdaBoostMHLearner(); sHypothesis->run(args, pTrainingData, _baseLearnerName, _numIterations, inWeakHypotheses ); delete sHypothesis; } else { cout << "[+] Loading uncalibrated shyp file... "; //read the shyp file of the trained classifier UnSerialization us; us.loadHypotheses(_unCalibratedShypFileName, inWeakHypotheses, pTrainingData); if (_inShypLimit > 0 && _inShypLimit < inWeakHypotheses.size() ) { inWeakHypotheses.resize(_inShypLimit); } if (_numIterations > inWeakHypotheses.size()) { _numIterations = inWeakHypotheses.size(); } cout << "weak hypotheses loaded, " << inWeakHypotheses.size() << " retained.\n"; } // some initializations _foundHypotheses.resize(0); double faceRejectionFraction = 0.; double estimatedExecutionTime = 0.; vector<double> rejectionDistributionVector; _rejectionThresholds.resize(0); set<int> trainingIndices; for (int i = 0; i < numExamples; i++) { trainingIndices.insert(pTrainingData->getRawIndex(i) ); } // init v_t (see the paper) initializeRejectionDistributionVector(_numIterations, rejectionDistributionVector); if (_verbose == 1) cout << "Learning in progress..." << endl; /////////////////////////////////////////////////////////////////////// // Starting the SoftCascade main loop /////////////////////////////////////////////////////////////////////// for (int t = 0; t < _numIterations; ++t) { if (_verbose > 0) cout << "--------------[ iteration " << (t+1) << " ]--------------" << endl; faceRejectionFraction += rejectionDistributionVector[t]; cout << "[+] Face rejection tolerated : " << faceRejectionFraction << " | v[t] = " << rejectionDistributionVector[t] << endl; int numberOfNegatives = pTrainingData->getNumExamplesPerClass(1 - _positiveLabelIndex); //vector<BaseLearner*>::const_iterator whyIt; int selectedIndex = 0; AlphaReal bestGap = 0; vector<AlphaReal> posteriors; computePosteriors(pTrainingData, _foundHypotheses, posteriors, _positiveLabelIndex); //should use an iterator instead of i vector<BaseLearner*>::iterator whyIt; int i; for (i = 0, whyIt = inWeakHypotheses.begin(); whyIt != inWeakHypotheses.end(); ++whyIt, ++i) { vector<AlphaReal> temporaryPosteriors = posteriors; vector<BaseLearner*> temporaryWeakHyp = _foundHypotheses; temporaryWeakHyp.push_back(*whyIt); updatePosteriors(pTrainingData, *whyIt, temporaryPosteriors, _positiveLabelIndex); AlphaReal gap = computeSeparationSpan(pTrainingData, temporaryPosteriors, _positiveLabelIndex ); if (gap > bestGap) { bestGap = gap; selectedIndex = i; } } BaseLearner* selectedWeakHypothesis = inWeakHypotheses[selectedIndex]; cout << "[+] Rank of the selected weak hypothesis : " << selectedIndex << endl << "\t ---> edge gap = " << bestGap << endl << "\t ---> alpha = " << selectedWeakHypothesis->getAlpha() << endl; //update the stages _foundHypotheses.push_back(selectedWeakHypothesis); updatePosteriors(pTrainingData, selectedWeakHypothesis, posteriors, _positiveLabelIndex); double missesFraction; AlphaReal r = findBestRejectionThreshold(pTrainingData, posteriors, faceRejectionFraction, missesFraction); _rejectionThresholds.push_back(r); // update the output info object dynamic_cast<SoftCascadeOutput*>( pOutInfo->getOutputInfoObject("sca") )->appendRejectionThreshold(r); cout << "[+] Rejection threshold = " << r << endl; //some updates ss.appendHypothesisWithThreshold(t, selectedWeakHypothesis, r); faceRejectionFraction -= missesFraction; inWeakHypotheses.erase(inWeakHypotheses.begin() + selectedIndex); double whypCost = 1; //just in case there are different costs for each whyp estimatedExecutionTime += whypCost * numberOfNegatives; // output perf in file vector< vector< AlphaReal> > scores(0); _output << t + 1 << setw(_sepWidth + 1) << r << setw(_sepWidth); // update OutputInfo with the new whyp // updateOutputInfo(pOutInfo, pTrainingData, selectedWeakHypothesis); // if (pTestData) { // updateOutputInfo(pOutInfo, pTestData, selectedWeakHypothesis); // } // output the iteration results printOutputInfo(pOutInfo, t, pTrainingData, pTestData, selectedWeakHypothesis, r); // if (pTrainPosteriorsOut) { // pTrainPosteriorsOut->setTable(pTrainingData, pOutInfo->getTable(pTrainingData)); // pTrainPosteriorsOut->outputCustom(pTrainingData); // } // // if (pTestPosteriorsOut) { // pTestPosteriorsOut->setTable(pTestData, pOutInfo->getTable(pTestData)); // pTestPosteriorsOut->outputCustom(pTestData); // } int leftNegatives = filterDataset(pTrainingData, posteriors, r, trainingIndices); if (leftNegatives == 0) { cout << endl << "[+] No more negatives.\n"; break; } if (_bootstrapRate != 0) { bootstrapTrainingSet(pTrainingData, pBootstrapData, trainingIndices); } } // loop on iterations ///////////////////////////////////////////////////////// // write the footer of the strong hypothesis file ss.writeFooter(); // Free the two input data objects if (pTrainingData) delete pTrainingData; if (pBootstrapData) { delete pBootstrapData; } if (pTestData) delete pTestData; if (_verbose > 0) cout << "Learning completed." << endl; }