123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- // Copyright 2008 Rarefied Technologies, Inc.
- // Distributed under the GPL v2 please see
- // LICENSE file for more information.
- #include "parametersearch.h"
- #include "parameterresult.h"
- #include "../thirdparty/libsvm/svm.h"
- #include <cmath>
- #include <iostream>
- #include <fstream>
- #define REFINED_RANGE 1.33
- CParameterSearch::CParameterSearch(svm_problem* pProb, svm_parameter* pSvmParam, string strFilename)
- {
- if(!pProb || !pSvmParam)
- return;
-
- m_pOA = NULL;
- m_pofs = NULL;
- m_strFilename = strFilename;
-
- ResetSerialization();
-
- m_pProblem = pProb;
- m_pSvmParam = pSvmParam;
- m_rangeParameters.fParam1Min = -15;
- //m_rangeParameters.fParam1Max = -1;
- m_rangeParameters.fParam1Max = 3;
- m_rangeParameters.fParam1Step = 4;
- m_rangeParameters.bParam1UseLog = true;
- m_rangeParameters.fParam1RefinementFactor = 2;
- m_rangeParameters.fParam2Min = -13;
- //m_rangeParameters.fParam2Max = -1;
- m_rangeParameters.fParam2Max = -5;
- m_rangeParameters.fParam2Step = 4;
- m_rangeParameters.bParam2UseLog = true;
- m_rangeParameters.fParam2RefinementFactor = 2;
-
- ParameterResult* pResult = new ParameterResult;
- const RangeParameters tempRP = m_rangeParameters;
- *m_pOA << tempRP;
- m_pofs->flush();
-
- SearchRange( pResult, m_rangeParameters);
-
- // semi-infinite, breakable loop
- while( pResult = GetNextResult())
- {
- RangeParameters Params;
- GetRefinedParameters(pResult->nLevel, pResult->fParam1, pResult->fParam2, Params);
- if(!SearchRange( pResult, Params))
- break;
- }
- }
- CParameterSearch::~CParameterSearch()
- {
-
- }
- ParameterResult* CParameterSearch::GetNextResult()
- {
- ParameterResult* pResult = NULL;
- ResultsSet::iterator it = m_searchResults.begin();
- while(it != m_searchResults.end())
- {
- pResult = *it;
- if(!pResult->bRefined)
- return pResult;
- ++it;
- }
- return NULL;
- }
- bool CParameterSearch::SearchRange(ParameterResult* pResult, RangeParameters& Params)
- {
- if(!m_pProblem || !m_pSvmParam || !pResult)
- return false;
-
- float fParam1 = 0;
- float fParam2 = 0;
-
- double* target = new double[m_pProblem->l];
- /* for(int i=0; i<m_pProblem->l; i++)
- {
- target[i] = 0;
- }*/
-
- for(fParam1=Params.fParam1Min; fParam1<=Params.fParam1Max; fParam1+=Params.fParam1Step)
- {
- if(Params.bParam1UseLog)
- m_pSvmParam->p = ::pow(2,fParam1);
- else
- m_pSvmParam->p = fParam1;
-
- for(fParam2=Params.fParam2Min; fParam2<=Params.fParam2Max; fParam2+=Params.fParam2Step)
- {
- if(Params.bParam2UseLog)
- m_pSvmParam->C = ::pow(2,fParam2);
- else
- m_pSvmParam->C = fParam2;
-
- int nFolds = 2;
- svm_cross_validation(m_pProblem, m_pSvmParam, nFolds, target);
- float fError = 0;
- float fWrong = 0;
- for(int i=0; i<m_pProblem->l; i++)
- {
- fError += abs(m_pProblem->y[i] - target[i]);
- if( m_pProblem->y[i] >= 0.5 && target[i] < 0.5)
- fWrong++;
- else if( m_pProblem->y[i] < 0.5 && target[i] >= 0.5)
- fWrong++;
- }
- fError = (float)fError/m_pProblem->l;
- fWrong = (float) fWrong/m_pProblem->l;
-
- float fStdDev = 0;
- for(int i=0; i<m_pProblem->l; i++)
- {
- fStdDev += pow(fError - abs(m_pProblem->y[i] - target[i]), 2) ;
- }
- fStdDev = pow(fStdDev, (float)0.5) / m_pProblem->l;
-
- std::cout << "\n****************" << std::endl;
- std::cout << "C = 2^" << fParam2 << ", epsilon = 2^" << fParam1 << std::endl;
- std::cout << "Avg Error: " << fError << " Std Dev: " << fStdDev << std::endl;
- std::cout << "Percent wrong: " << fWrong << std::endl;
-
- ParameterResult* pNewResult = new ParameterResult;
- pNewResult->fError = fError;
- pNewResult->fStdDev = fStdDev;
- pNewResult->fWrong = fWrong;
- pNewResult->fParam1 = fParam1;
- pNewResult->fParam2 = fParam2;
- pNewResult->nLevel = pResult->nLevel + 1;
- m_searchResults.insert(pNewResult);
-
- const ParameterResult* pConstResult = pNewResult;
-
- *m_pOA << *pConstResult;
- m_pofs->flush();
-
- //SaveTextResults();
- }
- }
- pResult->bRefined = true;
-
- SerializeData();
-
- return true;
- }
- // nLevel is desired level, not current level
- bool CParameterSearch::GetRefinedParameters(int nLevel, float fParam1, float fParam2, RangeParameters& paramsOut)
- {
- paramsOut.bParam1UseLog = m_rangeParameters.bParam1UseLog;
- float fParam1StepPrev = m_rangeParameters.fParam1Step / pow(m_rangeParameters.fParam1RefinementFactor, nLevel-1);
- paramsOut.fParam1Min = max( m_rangeParameters.fParam1Min, fParam1 - (float)REFINED_RANGE * fParam1StepPrev );
- paramsOut.fParam1Max = min( m_rangeParameters.fParam1Max, fParam1 + (float)REFINED_RANGE * fParam1StepPrev );
- paramsOut.fParam1Step = m_rangeParameters.fParam1Step / pow(m_rangeParameters.fParam1RefinementFactor, nLevel);
- paramsOut.bParam2UseLog = m_rangeParameters.bParam2UseLog;
- float fParam2StepPrev = m_rangeParameters.fParam2Step / pow(m_rangeParameters.fParam2RefinementFactor, nLevel-1);
- paramsOut.fParam2Min = max( m_rangeParameters.fParam2Min, fParam2 - (float)REFINED_RANGE * fParam2StepPrev );
- paramsOut.fParam2Max = min( m_rangeParameters.fParam2Max, fParam2 + (float)REFINED_RANGE * fParam2StepPrev );
- paramsOut.fParam2Step = m_rangeParameters.fParam2Step / pow(m_rangeParameters.fParam2RefinementFactor, nLevel);
-
- return true;
- }
- void CParameterSearch::ResetSerialization()
- {
- delete m_pOA;
- delete m_pofs;
-
- m_pofs = new std::ofstream(m_strFilename.c_str());
- m_pOA = new boost::archive::text_oarchive(*m_pofs);
- }
- void CParameterSearch::SerializeData()
- {
- ResetSerialization();
- const CParameterSearch* pSearch = this;
-
- *m_pOA << *pSearch;
-
- m_pofs->flush();
- }
- void CParameterSearch::SaveTextResults()
- {
- std::ofstream ofs("SearchResults.txt");
- ofs << *this;
- }
- std::ostream & operator<<(std::ostream &os, const CParameterSearch &ps)
- {
- os << ps.m_rangeParameters << std::endl << std::endl;
- ResultsSet::iterator it = ps.m_searchResults.begin();
- while(it != ps.m_searchResults.end())
- {
- const ParameterResult* pResult = *it;
-
- os << *pResult << '\n';
- ++it;
- }
- return os;
- }
|