AutomaticParameterTuner Class Reference

#include <AutomaticParameterTuner.h>

Inheritance diagram for AutomaticParameterTuner:

Framework Autoencoder BlendingNN BlendStopping StandardAlgorithm GBDT KernelRidgeRegression KNearestNeighbor LinearModel LinearModelNonNeg LogisticRegression NeuralNetwork NeuralNetworkRBMauto PolynomialRegression

List of all members.

Public Member Functions

 AutomaticParameterTuner ()
virtual ~AutomaticParameterTuner ()
void addEpochParameter (int *param, string name)
void addIntegerParameter (int *param, string name, int min=INT_MIN, int max=INT_MAX)
void addDoubleParameter (double *param, string name, double min=-DBL_MAX, double max=DBL_MAX)
void removeEpochParameter (string name)
void removeIntegerParameter (string name)
void removeDoubleParameter (string name)
virtual double calcRMSEonProbe ()=0
virtual double calcRMSEonBlend ()=0
virtual void saveBestPrediction ()=0
void simpleStochasticParameterFinder (double minProbeImpro=0.00002, int maxProbeEpochsWithoutImpro=100, double minBlendImpro=0.000001, int maxBlendEpochsWithoutImpro=200, double stdDev=0.1)
void setOptimizeProbeRmse (bool enable)
void setOptimizeBlendRmse (bool enable)
void setDebug (bool en)
void expSearcher (int minEpochs=0, int maxEpochs=200, int paramEpochs=3, int accelerationEpochs=2, double expInit=0.8, bool enableProbe=true, bool enableBlend=true)
void expSearchParams (int minEpochs=0, int maxEpochs=100, int paramEpochs=3, int accelerationEpochs=10000, double expInit=0.8)
bool expSearchChangeParams ()
void expSearchCheckErr (double error)
void expSearchReinitStepSize ()
void expSearchSetEpochsToMinimizeBlend (int epochs)
double expSearchGetLowestError ()
void NelderMeadSearch (int maxEpochs=200)

Protected Member Functions

double calcError (const vector< double > &paramVector)
void setCurrentParameter (const vector< double > &paramVector)
void calcCenter (const vector< pair< double, vector< double > > > &simplexPoints, vector< double > &center)
double getReflectionPoint (const vector< double > &center, const vector< double > &worstPoint, vector< double > &reflectionPoint, double alpha)
void plotParameters (int epoch, const vector< pair< double, vector< double > > > &simplexPoints)
void calcMinMax (const vector< pair< double, vector< double > > > &simplexPoints, int paramNr, double &min, double &max)

Protected Attributes

int m_expSearchMinEpochs
int m_expSearchMaxEpochs
int m_expSearchMaxEpochsBlend
int m_expSearchParamEpochs
int m_expSearchParamAccelerationEpochs
int m_expSearchEpoch
int m_epochParamPos
bool m_epochParamBreak
int m_expSearchDoubleParamPos
int m_expSearchIntParamPos
int m_expSearchVariationCnt
double m_expInit
double m_expSearchErrorBest
double m_expSearchAcceleration
int m_expSearchAccelerationEpoch
time_t m_expSearchTime
vector< int > m_epochParamBest
vector< double > m_expSearchExponent
vector< double > m_expSearchDoubleParamBest
vector< int > m_expSearchIntParamBest
vector< double > m_expSearchParamDirection
vector< int * > m_epochParam
vector< string > m_epochName
vector< double * > m_doubleParam
vector< string > m_doubleName
vector< int * > m_intParam
vector< string > m_intName
vector< double > m_doubleMin
vector< double > m_doubleMax
vector< int > m_intMin
vector< int > m_intMax
bool m_optimizeProbeRMSE
bool m_optimizeBlendRMSE
bool m_enableDebug


Detailed Description

Automatic Parameter Tuner

This is used to tune some parameters in order to minimize a error function Two different error function templates:

The Algorithm class should be derived from this class to call the optimization functions In the Algorithm class there should be a reimplementation of the two methods from above And in those functions the error evaluation should be done there

Three different optimizers are implemented here

Definition at line 37 of file AutomaticParameterTuner.h.


Constructor & Destructor Documentation

AutomaticParameterTuner::AutomaticParameterTuner (  ) 

Constructor

Definition at line 8 of file AutomaticParameterTuner.cpp.

00009 {
00010     // first enable both optimizers
00011     m_optimizeProbeRMSE = true;
00012     m_optimizeBlendRMSE = true;
00013 
00014     m_expSearchMaxEpochsBlend = -1;
00015 
00016     m_enableDebug = true;
00017 
00018     m_epochParamBreak = false;
00019 }

AutomaticParameterTuner::~AutomaticParameterTuner (  )  [virtual]

Descructor

Definition at line 24 of file AutomaticParameterTuner.cpp.

00025 {
00026 }


Member Function Documentation

void AutomaticParameterTuner::addDoubleParameter ( double *  param,
string  name,
double  min = -DBL_MAX,
double  max = DBL_MAX 
)

Add a double parameter

Parameters:
param The pointer to the double
name The name (string)
min Minimal value during tuninig
max Maximal value during tuninig

Definition at line 65 of file AutomaticParameterTuner.cpp.

00066 {
00067     m_doubleParam.push_back ( param );
00068     m_doubleMin.push_back ( min );
00069     m_doubleMax.push_back ( max );
00070     m_doubleName.push_back ( name );
00071 }

void AutomaticParameterTuner::addEpochParameter ( int *  param,
string  name 
)

Add an epoch parameter Useful for tune gradient descent Algorithms (or neural networks)

Parameters:
param The pointer to the integer
name The name (string)

Definition at line 35 of file AutomaticParameterTuner.cpp.

00036 {
00037     m_epochParam.push_back ( param );
00038     m_epochName.push_back ( name );
00039 }

void AutomaticParameterTuner::addIntegerParameter ( int *  param,
string  name,
int  min = INT_MIN,
int  max = INT_MAX 
)

Add an integer parameter

Parameters:
param The pointer to the integer
name The name (string)
min Minimal value during tuninig
max Maximal value during tuninig

Definition at line 49 of file AutomaticParameterTuner.cpp.

00050 {
00051     m_intParam.push_back ( param );
00052     m_intMin.push_back ( min );
00053     m_intMax.push_back ( max );
00054     m_intName.push_back ( name );
00055 }

void AutomaticParameterTuner::calcCenter ( const vector< pair< double, vector< double > > > &  simplexPoints,
vector< double > &  center 
) [protected]

Calc the new center

Parameters:
simplexPoints points of the simplex
center the new center

Definition at line 945 of file AutomaticParameterTuner.cpp.

00946 {
00947     center.resize ( simplexPoints[0].second.size() );
00948 
00949     for ( int i=0; i < center.size(); i++ )
00950         center[i] = 0.0;
00951 
00952     for ( int i=0; i < simplexPoints.size()-1; i++ )
00953     {
00954         for ( int j=0; j < center.size(); j++ )
00955             center[j] += ( simplexPoints[i].second ) [j];
00956     }
00957 
00958     for ( int i=0; i < center.size(); i++ )
00959         center[i] /= ( double ) ( simplexPoints.size()-1 );
00960 }

double AutomaticParameterTuner::calcError ( const vector< double > &  paramVector  )  [protected]

Get the error

Parameters:
paramVector references to the double paremeters
Returns:
the error

Definition at line 900 of file AutomaticParameterTuner.cpp.

00901 {
00902     setCurrentParameter ( paramVector );
00903 
00904     return calcRMSEonProbe();
00905 }

void AutomaticParameterTuner::calcMinMax ( const vector< pair< double, vector< double > > > &  simplexPoints,
int  paramNr,
double &  min,
double &  max 
) [protected]

calc min and max errors

Parameters:
simplexPoints simplex points
paramNr param id
min reference to min
max reference to max

Definition at line 1026 of file AutomaticParameterTuner.cpp.

01027 {
01028     min = DBL_MAX;
01029     max = DBL_MIN;
01030 
01031     for ( int i=0; i < simplexPoints.size(); i++ )
01032     {
01033         double value = simplexPoints[i].second.at ( paramNr );
01034 
01035         if ( value < min )
01036             min = value;
01037         if ( value > max )
01038             max = value;
01039     }
01040 }

bool AutomaticParameterTuner::expSearchChangeParams (  ) 

Vary a specific parameter

Returns:
The break criteria: false=break search

Definition at line 407 of file AutomaticParameterTuner.cpp.

00408 {
00409     m_expSearchTime = time ( 0 );
00410     m_expSearchEpoch++;
00411 
00412     if ( m_enableDebug )
00413         cout<<"(epoch="<<m_expSearchEpoch-1<<") "<<flush;
00414 
00415     // break training if error rises on epoch tuninig and larger as minEpochs
00416     if ( m_epochParamBreak &&  m_expSearchEpoch >= m_expSearchMinEpochs )
00417     {
00418         if ( m_enableDebug )
00419             cout<<"epoch training error rises. (#minEpochs:"<<m_expSearchMinEpochs<<", )"<<endl;
00420         return false;
00421     }
00422 
00423     // in the first epoch do nothing
00424     if ( m_expSearchEpoch==1 )
00425     {
00426         for ( int i=0;i<m_epochParam.size();i++ )
00427             if ( m_enableDebug )
00428                 cout<<m_epochName[i]<<"="<< ( *m_epochParam[i] ) <<" ";
00429         for ( int i=0;i<m_doubleParam.size();i++ )
00430             if ( m_enableDebug )
00431                 cout<<m_doubleName[i]<<"="<< ( *m_doubleParam[i] ) <<" ";
00432         for ( int i=0;i<m_intParam.size();i++ )
00433             if ( m_enableDebug )
00434                 cout<<m_intName[i]<<"="<< ( *m_intParam[i] ) <<" ";
00435         return true;
00436     }
00437 
00438     // change a epoch parameter
00439     if ( m_epochParamPos < m_epochParam.size() )
00440     {
00441         // do the change
00442         *m_epochParam[m_epochParamPos] = *m_epochParam[m_epochParamPos] + 1;
00443     }
00444 
00445     // change a double parameter
00446     if ( m_expSearchDoubleParamPos < m_doubleParam.size() && m_epochParamPos == m_epochParam.size() )
00447     {
00448         int pos = m_expSearchDoubleParamPos;
00449         double exp = m_expSearchExponent[pos];
00450         bool dir = m_expSearchParamDirection[pos];
00451         double best = m_expSearchDoubleParamBest[pos];
00452 
00453         // do the change
00454         *m_doubleParam[pos] = best * ( dir? ( 1.0/exp ) : exp );
00455 
00456         // check boundaries
00457         if ( *m_doubleParam[pos] > m_doubleMax[pos] )
00458             *m_doubleParam[pos] = m_doubleMax[pos];
00459         if ( *m_doubleParam[pos] < m_doubleMin[pos] )
00460             *m_doubleParam[pos] = m_doubleMin[pos];
00461     }
00462 
00463     // change a int parameter
00464     if ( m_expSearchIntParamPos < m_intParam.size() && m_expSearchDoubleParamPos == m_doubleParam.size() )
00465     {
00466         int pos = m_expSearchIntParamPos;
00467         double exp = m_expSearchExponent[pos + m_doubleParam.size() ];
00468         bool dir = m_expSearchParamDirection[pos + m_doubleParam.size() ];
00469         int best = m_expSearchIntParamBest[pos];
00470 
00471         // do the change
00472         *m_intParam[pos] = ( int ) ( round ( ( double ) ( best ) * ( dir? ( 1.0/exp ) : exp ) ) );
00473 
00474         // if no change, force the change
00475         if ( best == *m_intParam[pos] )
00476             *m_intParam[pos] = dir? best+1 : best-1;
00477 
00478         // check boundaries
00479         if ( *m_intParam[pos] > m_intMax[pos] )
00480             *m_intParam[pos] = m_intMax[pos];
00481         if ( *m_intParam[pos] < m_intMin[pos] )
00482             *m_intParam[pos] = m_intMin[pos];
00483     }
00484 
00485     for ( int i=0;i<m_epochParam.size();i++ )
00486         if ( m_enableDebug )
00487             cout<<m_epochName[i]<<"="<< ( *m_epochParam[i] ) <<" ";
00488     for ( int i=0;i<m_doubleParam.size();i++ )
00489         if ( m_enableDebug )
00490             cout<<m_doubleName[i]<<"="<< ( *m_doubleParam[i] ) <<" ";
00491     for ( int i=0;i<m_intParam.size();i++ )
00492         if ( m_enableDebug )
00493             cout<<m_intName[i]<<"="<< ( *m_intParam[i] ) <<" ";
00494 
00495     // break, if maxEpochs is reached
00496     if ( m_expSearchEpoch > m_expSearchMaxEpochs )
00497     {
00498         m_expSearchEpoch = 0;
00499         // apply best
00500         for ( int i=0;i<m_epochParam.size();i++ )
00501             *m_epochParam[i] = m_epochParamBest[i];
00502         for ( int i=0;i<m_doubleParam.size();i++ )
00503             *m_doubleParam[i] = m_expSearchDoubleParamBest[i];
00504         for ( int i=0;i<m_intParam.size();i++ )
00505             *m_intParam[i] = m_expSearchIntParamBest[i];
00506         if ( m_enableDebug )
00507             cout<<"max. epochs reached."<<endl;
00508         return false;
00509     }
00510 
00511     return true;
00512 }

void AutomaticParameterTuner::expSearchCheckErr ( double  error  ) 

Check if the error gets lower If the error is lower, set the new parameter as best

Parameters:
error The error from an error function, which is to minimize

Definition at line 520 of file AutomaticParameterTuner.cpp.

00521 {
00522     if ( m_enableDebug )
00523         cout<<"ERR="<<error;
00524 
00525     if ( m_enableDebug )
00526         cout<<" "<<time ( 0 )-m_expSearchTime<<"[s]";
00527 
00528     // in the first epoch do nothing
00529     if ( m_expSearchEpoch==1 )
00530     {
00531         saveBestPrediction();
00532         for ( int i=0;i<m_epochParam.size();i++ )
00533             m_epochParamBest[i] = *m_epochParam[i];
00534         for ( int i=0;i<m_doubleParam.size();i++ )
00535             m_expSearchDoubleParamBest[i] = *m_doubleParam[i];
00536         for ( int i=0;i<m_intParam.size();i++ )
00537             m_expSearchIntParamBest[i] = *m_intParam[i];
00538         m_expSearchErrorBest = error;
00539         if ( m_enableDebug )
00540             cout<<endl;
00541         return;
00542     }
00543 
00544     // if the error is lower than the old
00545     if ( error<m_expSearchErrorBest )
00546     {
00547         m_expSearchErrorBest = error;
00548         //cout<<"bestUpdate:"<<m_expSearchErrorBest<<" ";
00549 
00550         m_epochParamBreak = 0;
00551 
00552         if ( m_enableDebug )
00553             cout<<" !min! ";
00554         saveBestPrediction();
00555 
00556         // current in a epoch parameter
00557         if ( m_epochParamPos < m_epochParam.size() )
00558         {
00559             m_epochParamBest[m_epochParamPos] = *m_epochParam[m_epochParamPos];
00560         }
00561 
00562         // current in a double parameter
00563         if ( m_expSearchDoubleParamPos < m_doubleParam.size() && m_epochParamPos == m_epochParam.size() )
00564         {
00565             int pos = m_expSearchDoubleParamPos;
00566             double exp = m_expSearchExponent[pos];
00567             bool dir = m_expSearchParamDirection[pos];
00568 
00569             // new best value
00570             m_expSearchDoubleParamBest[pos] = *m_doubleParam[pos];
00571 
00572             // if we go in the right direction, increase step size
00573             if ( m_expSearchAccelerationEpoch >= m_expSearchParamAccelerationEpochs )
00574             {
00575                 if ( m_enableDebug )
00576                     cout<<" accelerate ";
00577                 m_expSearchExponent[pos] = pow ( m_expSearchExponent[pos], 1.0/m_expSearchAcceleration );
00578             }
00579 
00580         }
00581 
00582         // current in a int parameter
00583         if ( m_expSearchIntParamPos < m_intParam.size() && m_expSearchDoubleParamPos == m_doubleParam.size() )
00584         {
00585             int pos = m_expSearchIntParamPos;
00586             double exp = m_expSearchExponent[pos + m_doubleParam.size() ];
00587             bool dir = m_expSearchParamDirection[pos + m_doubleParam.size() ];
00588 
00589             // new best value
00590             m_expSearchIntParamBest[pos] = *m_intParam[pos];
00591 
00592             // if we go in the right direction, increase step size
00593             if ( m_expSearchAccelerationEpoch >= m_expSearchParamAccelerationEpochs )
00594             {
00595                 if ( m_enableDebug )
00596                     cout<<" accelerate ";
00597                 m_expSearchExponent[pos] = pow ( m_expSearchExponent[pos], 1.0/m_expSearchAcceleration );
00598             }
00599         }
00600 
00601         m_expSearchAccelerationEpoch++;
00602     }
00603     else  // error gets higher, so change search direction and decrease step size
00604     {
00605         // current in a epoch parameter
00606         if ( m_epochParamPos < m_epochParam.size() )
00607         {
00608             // break training
00609             m_epochParamBreak = true;
00610         }
00611 
00612         // current in a double parameter
00613         if ( m_expSearchDoubleParamPos < m_doubleParam.size() && m_epochParamPos == m_epochParam.size() )
00614         {
00615             int pos = m_expSearchDoubleParamPos;
00616             bool dir = m_expSearchParamDirection[pos];
00617             m_expSearchParamDirection[pos] = !m_expSearchParamDirection[pos];
00618             m_expSearchExponent[pos] = pow ( m_expSearchExponent[pos], m_expSearchAcceleration );
00619         }
00620 
00621         // current in a int parameter
00622         if ( m_expSearchIntParamPos < m_intParam.size() && m_expSearchDoubleParamPos == m_doubleParam.size() )
00623         {
00624             int pos = m_expSearchIntParamPos;
00625             bool dir = m_expSearchParamDirection[pos + m_doubleParam.size() ];
00626             m_expSearchParamDirection[pos + m_doubleParam.size() ] = !m_expSearchParamDirection[pos + m_doubleParam.size() ];
00627             m_expSearchExponent[pos + m_doubleParam.size() ] = pow ( m_expSearchExponent[pos + m_doubleParam.size() ], m_expSearchAcceleration );
00628         }
00629 
00630         m_expSearchAccelerationEpoch = 0;
00631     }
00632 
00633 
00634     // goto next parameter, current in a epoch parameter
00635     if ( m_epochParamPos < m_epochParam.size() )
00636     {
00637         m_epochParamPos++;
00638 
00639         // if no integer and no double parameter available
00640         if ( m_doubleParam.size() == 0 && m_intParam.size() == 0 && m_epochParamPos == m_epochParam.size() )
00641             m_epochParamPos = 0;
00642     }
00643 
00644     // goto next parameter, current in a double parameter
00645     if ( m_expSearchDoubleParamPos < m_doubleParam.size() && m_epochParamPos == m_epochParam.size() )
00646     {
00647         // change to next parameter
00648         m_expSearchVariationCnt++;
00649         if ( m_expSearchVariationCnt==m_expSearchParamEpochs )
00650         {
00651             m_expSearchAccelerationEpoch = 0;
00652             m_expSearchVariationCnt = 0;
00653             *m_doubleParam[m_expSearchDoubleParamPos] = m_expSearchDoubleParamBest[m_expSearchDoubleParamPos];  // apply best
00654             m_expSearchDoubleParamPos++;
00655         }
00656 
00657         // if no integer parameter available
00658         if ( m_intParam.size() == 0 && m_expSearchDoubleParamPos == m_doubleParam.size() )
00659             m_expSearchDoubleParamPos = 0;
00660     }
00661 
00662     // goto next parameter, current in a int parameter
00663     if ( m_expSearchIntParamPos < m_intParam.size() && m_expSearchDoubleParamPos == m_doubleParam.size() )
00664     {
00665         // change to next parameter
00666         m_expSearchVariationCnt++;
00667         if ( m_expSearchVariationCnt==m_expSearchParamEpochs )
00668         {
00669             m_expSearchAccelerationEpoch = 0;
00670             m_expSearchVariationCnt = 0;
00671             *m_intParam[m_expSearchIntParamPos] = m_expSearchIntParamBest[m_expSearchIntParamPos];  // apply best
00672             m_expSearchIntParamPos++;
00673         }
00674 
00675         if ( m_expSearchIntParamPos == m_intParam.size() )
00676         {
00677             m_epochParamPos = 0;
00678             m_expSearchIntParamPos = 0;
00679             m_expSearchDoubleParamPos = 0;
00680         }
00681     }
00682 
00683     if ( m_enableDebug )
00684         cout<<endl;
00685 }

void AutomaticParameterTuner::expSearcher ( int  minEpochs = 0,
int  maxEpochs = 200,
int  paramEpochs = 3,
int  accelerationEpochs = 2,
double  expInit = 0.8,
bool  enableProbe = true,
bool  enableBlend = true 
)

Structured coordinate searcher Goes through all params and go to the direction where error gets minimal Search for best parameters

Parameters:
minEpochs Min. number of parameter variations
maxEpochs Max. number of parameter variations
paramEpochs Number of variations per parameter until jump to the next
accelerationEpochs If the error decreases accelerationEpochs-times, the search speed increases
expInit The init value of the exponential search: newValue = oldValue * (exponent^(+/-)1)
enableProbe Enable to optimize first on probeRMSE
enableBlend Enable to optimize on blendRMSE

Definition at line 700 of file AutomaticParameterTuner.cpp.

00701 {
00702     if ( enableProbe==0 && enableBlend==0 )
00703     {
00704         cout<<"Warning: both enableProbe and enableBlend are 0"<<endl;
00705         cout<<"Skip tuning"<<endl;
00706     }
00707 
00708     if ( maxEpochs == 0 )
00709         return;
00710 
00711     m_epochParamBreak = false;
00712 
00713     expSearchParams ( minEpochs, maxEpochs, paramEpochs, accelerationEpochs, expInit );
00714     m_optimizeProbeRMSE = enableProbe;
00715     m_optimizeBlendRMSE = enableBlend;
00716 
00717     // minimize on probe
00718     if ( m_optimizeProbeRMSE )
00719     {
00720         double error;
00721         while ( expSearchChangeParams() )
00722         {
00723             error = calcRMSEonProbe();
00724             expSearchCheckErr ( error );
00725         }
00726         if ( m_enableDebug )
00727             cout<<"expSearchErrorBest:"<<m_expSearchErrorBest<<"  error:"<<error<<endl;
00728     }
00729     // minimize on blend
00730     if ( m_optimizeBlendRMSE )
00731     {
00732         // if no explicit specified
00733         if ( m_expSearchMaxEpochsBlend == -1 )
00734             m_expSearchMaxEpochsBlend = m_expSearchMaxEpochs;
00735 
00736         expSearchParams ( m_expSearchMinEpochs, m_expSearchMaxEpochsBlend, paramEpochs, accelerationEpochs, expInit );
00737 
00738         if ( m_enableDebug )
00739             cout<<endl<<endl<<"==================== auto-optimize ===================="<<endl<<endl;
00740 
00741         double error;
00742         while ( expSearchChangeParams() )
00743         {
00744             error = calcRMSEonBlend();
00745             expSearchCheckErr ( error );
00746         }
00747         if ( m_enableDebug )
00748             cout<<"expSearchErrorBest:"<<m_expSearchErrorBest<<"  error:"<<error<<endl;
00749     }
00750 }

double AutomaticParameterTuner::expSearchGetLowestError (  ) 

Return best error during search

Returns:
best error (lowest)

Definition at line 785 of file AutomaticParameterTuner.cpp.

00786 {
00787     return m_expSearchErrorBest;
00788 }

void AutomaticParameterTuner::expSearchParams ( int  minEpochs = 0,
int  maxEpochs = 100,
int  paramEpochs = 3,
int  accelerationEpochs = 10000,
double  expInit = 0.8 
)

Exponential parameter serach Set the search behaviour

Parameters:
minEpochs Min. number of parameter variations
maxEpochs Max. number of parameter variations
paramEpochs Number of variations per parameter until jump to the next
accelerationEpochs If the error decreases accelerationEpochs-times, the search speed increases
expInit The init value of the exponential search: newValue = oldValue * (exponent^(+/-)1)

Definition at line 362 of file AutomaticParameterTuner.cpp.

00363 {
00364     m_expSearchMinEpochs = minEpochs;
00365     m_expSearchMaxEpochs = maxEpochs;
00366     m_expSearchParamEpochs = paramEpochs;
00367     m_expSearchParamAccelerationEpochs = accelerationEpochs;
00368     m_expSearchEpoch = 0;
00369     m_expSearchVariationCnt = 0;
00370 
00371     m_epochParamPos = 0;
00372     m_expSearchDoubleParamPos = 0;
00373     m_expSearchIntParamPos = 0;
00374     m_expSearchErrorBest = 1e10;
00375     m_expSearchAcceleration = 0.8;
00376     m_expSearchAccelerationEpoch = 0;
00377 
00378     m_epochParamBest.clear();
00379     m_expSearchExponent.clear();
00380     m_expSearchDoubleParamBest.clear();
00381     m_expSearchIntParamBest.clear();
00382     m_expSearchParamDirection.clear();
00383 
00384     m_expInit = expInit;
00385 
00386     for ( int i=0;i<m_epochParam.size();i++ )
00387         m_epochParamBest.push_back ( *m_epochParam[i] );
00388     for ( int i=0;i<m_doubleParam.size();i++ )
00389     {
00390         m_expSearchExponent.push_back ( expInit );
00391         m_expSearchParamDirection.push_back ( false );
00392         m_expSearchDoubleParamBest.push_back ( *m_doubleParam[i] );
00393     }
00394     for ( int i=0;i<m_intParam.size();i++ )
00395     {
00396         m_expSearchExponent.push_back ( expInit );
00397         m_expSearchParamDirection.push_back ( false );
00398         m_expSearchIntParamBest.push_back ( *m_intParam[i] );
00399     }
00400 }

void AutomaticParameterTuner::expSearchReinitStepSize (  ) 

Reinit the step size Use this to make the same large steps as in the begin of search

Definition at line 756 of file AutomaticParameterTuner.cpp.

00757 {
00758     if ( m_enableDebug )
00759         cout<<"Reinit exp search step to "<<m_expInit<<endl;
00760     m_expSearchDoubleParamPos = 0;
00761     m_expSearchIntParamPos = 0;
00762     m_expSearchErrorBest = 1e10;
00763     m_expSearchAcceleration = 0.8;
00764     m_expSearchAccelerationEpoch = 0;
00765     for ( int i=0;i<m_expSearchExponent.size();i++ )
00766         m_expSearchExponent[i] = m_expInit;
00767 }

void AutomaticParameterTuner::expSearchSetEpochsToMinimizeBlend ( int  epochs  ) 

Reinit the step size Use this to make the same large steps as in the begin of search

Parameters:
epochs The maximal blend optimizing epochs

Definition at line 775 of file AutomaticParameterTuner.cpp.

00776 {
00777     m_expSearchMaxEpochsBlend = epochs;
00778 }

double AutomaticParameterTuner::getReflectionPoint ( const vector< double > &  center,
const vector< double > &  worstPoint,
vector< double > &  reflectionPoint,
double  alpha 
) [protected]

Returns the reflection point

Parameters:
center the current center
worstPoint the worst point
reflectionPoint the reflection point
alpha step size dependent parameter
Returns:
the error

Definition at line 971 of file AutomaticParameterTuner.cpp.

00972 {
00973     int N = center.size();
00974     reflectionPoint.resize ( N );
00975 
00976     for ( int i=0; i < N; i++ )
00977         reflectionPoint[i] = center[i] + alpha* ( center[i] - worstPoint[i] );
00978 
00979     return calcError ( reflectionPoint );
00980 }

void AutomaticParameterTuner::NelderMeadSearch ( int  maxEpochs = 200  ) 

Start the nelder-mead search

Parameters:
maxEpochs max search steps

Definition at line 798 of file AutomaticParameterTuner.cpp.

00799 {
00800     int N = m_doubleParam.size() + m_intParam.size();
00801     vector<pair<double,vector<double> > > simplexPoints ( N+1 );
00802 
00803     // set the initial simplex
00804     for ( int i=0; i < N+1; i++ )
00805     {
00806         simplexPoints[i].second.resize ( N );
00807         for ( int j=0; j < m_doubleParam.size(); j++ )
00808             ( simplexPoints[i].second ) [j] = *m_doubleParam[j];
00809         for ( int j=0; j < m_intParam.size(); j++ )
00810             ( simplexPoints[i].second ) [j+m_doubleParam.size() ] = *m_intParam[j];
00811 
00812         if ( i < N )
00813             //(simplexPoints[i].second)[i] = (simplexPoints[i].second)[i] + fabs((simplexPoints[i].second)[i]) * 2.0;
00814             ( simplexPoints[i].second ) [i] = ( simplexPoints[i].second ) [i] + max ( 1.0,fabs ( ( simplexPoints[i].second ) [i] ) *2.0 );
00815     }
00816 
00817     for ( int i=0; i < N+1; i++ )
00818         simplexPoints[i].first = calcError ( simplexPoints[i].second );
00819 
00820     for ( int epoch =0; epoch < maxEpochs; epoch++ )
00821     {
00822         vector<double> center ( N );
00823 
00824         sort ( simplexPoints.begin(),simplexPoints.end() );
00825         calcCenter ( simplexPoints, center );
00826         plotParameters ( epoch, simplexPoints );
00827 
00828         // refelction
00829         vector<double> reflectionPoint ( N );
00830         double reflectionError = getReflectionPoint ( center,simplexPoints[N].second,reflectionPoint,1.0 );
00831 
00832         if ( ( reflectionError <= simplexPoints[N-1].first ) && ( reflectionError >= simplexPoints[0].first ) )
00833         {
00834             simplexPoints[N].second = reflectionPoint;
00835             simplexPoints[N].first = reflectionError;
00836             continue;
00837         }
00838 
00839         // expansion (the new point is the best so far)
00840         if ( reflectionError < simplexPoints[0].first )
00841         {
00842             vector<double> expansionPoint ( N );
00843             double expansionError = getReflectionPoint ( center,simplexPoints[N].second,expansionPoint,2.0 );
00844 
00845             if ( expansionError < reflectionError )
00846             {
00847                 simplexPoints[N].second = expansionPoint;
00848                 simplexPoints[N].first = expansionError;
00849                 continue;
00850             }
00851             else
00852             {
00853                 simplexPoints[N].second = reflectionPoint;
00854                 simplexPoints[N].first = reflectionError;
00855                 continue;
00856             }
00857         }
00858 
00859         // contraction (the new point is the worst so far)
00860         vector<double> contractionPoint ( N );
00861         double contractionError, refError;
00862         if ( reflectionError <= simplexPoints[N].first )
00863         {   // outside contraction
00864             refError = reflectionError;
00865             contractionError = getReflectionPoint ( center,reflectionPoint,contractionPoint,0.5 );
00866         }
00867         else
00868         {   // inside contraction
00869             refError = simplexPoints[N].first;
00870             contractionError = getReflectionPoint ( center,simplexPoints[N].second,contractionPoint,0.5 );
00871         }
00872 
00873         if ( contractionError <= refError )
00874         {
00875             simplexPoints[N].second = contractionPoint;
00876             simplexPoints[N].first = contractionError;
00877             continue;
00878         }
00879 
00880         // reduction
00881         for ( int j=1; j < N+1; j++ )
00882         {
00883             vector<double> reductionPoint ( N );
00884             double reductionError = getReflectionPoint ( center,simplexPoints[j].second, reductionPoint, 0.5 );
00885             simplexPoints[j].second = reductionPoint;
00886             simplexPoints[j].first = reductionError;
00887         }
00888     }
00889 
00890     sort ( simplexPoints.begin(),simplexPoints.end() );
00891     setCurrentParameter ( simplexPoints[0].second );
00892 }

void AutomaticParameterTuner::plotParameters ( int  epoch,
const vector< pair< double, vector< double > > > &  simplexPoints 
) [protected]

print parameter values nicely

Parameters:
epoch the current epoch
simplexPoints the simplex points

Definition at line 988 of file AutomaticParameterTuner.cpp.

00989 {
00990     static time_t t0 = time ( 0 );
00991 
00992     if ( m_enableDebug )
00993         cout<<epoch<<". | error: ["<<simplexPoints[0].first<<"-"<<simplexPoints[simplexPoints.size()-1].first<<"] ";
00994 
00995     for ( int i=0; i < m_doubleParam.size(); i++ )
00996     {
00997         double min,max;
00998         calcMinMax ( simplexPoints,i,min,max );
00999         if ( m_enableDebug )
01000             cout<<" | "<<m_doubleName[i]<<": ["<<min<<" - "<<max<<"]";
01001     }
01002 
01003     for ( int i=0; i < m_intParam.size(); i++ )
01004     {
01005         int param = i+m_doubleParam.size();
01006         double min,max;
01007         calcMinMax ( simplexPoints,param,min,max );
01008         if ( m_enableDebug )
01009             cout<<" | "<<m_intName[i]<<": ["<<min<<" - "<<max<<"]";
01010     }
01011 
01012     time_t t1 = time ( 0 );
01013     if ( m_enableDebug )
01014         cout<<" | "<<t1-t0<<"[s]"<<endl;
01015     t0=t1;
01016 }

void AutomaticParameterTuner::removeDoubleParameter ( string  name  ) 

Remove a double parameter

Parameters:
name The name of the parameter (string)

Definition at line 122 of file AutomaticParameterTuner.cpp.

00123 {
00124     int pos = -1;
00125     for ( int i=0;i<m_doubleName.size();i++ )
00126         if ( m_doubleName[i] == name )
00127             pos = i;
00128     if ( pos != -1 )
00129     {
00130         //cout<<"Remove double parameter:"<<name<<endl;
00131         m_doubleName.erase ( m_doubleName.begin() +pos );
00132         m_doubleParam.erase ( m_doubleParam.begin() +pos );
00133         m_doubleMin.erase ( m_doubleMin.begin() +pos );
00134         m_doubleMax.erase ( m_doubleMax.begin() +pos );
00135     }
00136     else
00137         cout<<"Warning: double parameter:"<<name<<" cannot be removed"<<endl;
00138 }

void AutomaticParameterTuner::removeEpochParameter ( string  name  ) 

Remove an epoch parameter

Parameters:
name The name of the parameter (string)

Definition at line 78 of file AutomaticParameterTuner.cpp.

00079 {
00080     int pos = -1;
00081     for ( int i=0;i<m_epochName.size();i++ )
00082         if ( m_epochName[i] == name )
00083             pos = i;
00084     if ( pos != -1 )
00085     {
00086         //cout<<"Remove epoch parameter:"<<name<<endl;
00087         m_epochName.erase ( m_epochName.begin() +pos );
00088         m_epochParam.erase ( m_epochParam.begin() +pos );
00089     }
00090     else
00091         cout<<"Warning: epoch parameter:"<<name<<" cannot be removed"<<endl;
00092 }

void AutomaticParameterTuner::removeIntegerParameter ( string  name  ) 

Remove an integer parameter

Parameters:
name The name of the parameter (string)

Definition at line 99 of file AutomaticParameterTuner.cpp.

00100 {
00101     int pos = -1;
00102     for ( int i=0;i<m_intName.size();i++ )
00103         if ( m_intName[i] == name )
00104             pos = i;
00105     if ( pos != -1 )
00106     {
00107         //cout<<"Remove int parameter:"<<name<<endl;
00108         m_intName.erase ( m_intName.begin() +pos );
00109         m_intParam.erase ( m_intParam.begin() +pos );
00110         m_intMin.erase ( m_intMin.begin() +pos );
00111         m_intMax.erase ( m_intMax.begin() +pos );
00112     }
00113     else
00114         cout<<"Warning: int parameter:"<<name<<" cannot be removed"<<endl;
00115 }

void AutomaticParameterTuner::setCurrentParameter ( const vector< double > &  paramVector  )  [protected]

Modify a parameter

Parameters:
paramVector the references to the double parameters

Definition at line 912 of file AutomaticParameterTuner.cpp.

00913 {
00914     for ( int i=0; i < m_doubleParam.size(); i++ )
00915     {
00916         double value = paramVector[i];
00917 
00918         if ( value <= m_doubleMin[i] )
00919             value = m_doubleMin[i];
00920         if ( value >= m_doubleMax[i] )
00921             value = m_doubleMax[i];
00922 
00923         *m_doubleParam[i] = value;
00924     }
00925 
00926     for ( int i=0; i < m_intParam.size(); i++ )
00927     {
00928         int value = ( int ) ( 0.5 + paramVector[i + m_doubleParam.size() ] );
00929 
00930         if ( value <= m_intMin[i] )
00931             value = m_intMin[i];
00932         if ( value >= m_intMax[i] )
00933             value = m_intMax[i];
00934 
00935         *m_intParam[i] = value;
00936     }
00937 }

void AutomaticParameterTuner::setDebug ( bool  en  ) 

For structured parameter search, to enable debug output (recommended)

Parameters:
en Enable bit

Definition at line 346 of file AutomaticParameterTuner.cpp.

00347 {
00348     m_enableDebug = en;
00349     //cout<<"Debug: "<<m_enableDebug<<endl;
00350 }

void AutomaticParameterTuner::setOptimizeBlendRmse ( bool  enable  ) 

For stochastic parameter tuner, to enable optimizing the calcRMSEonBlend()

Parameters:
enable Enable bit

Definition at line 336 of file AutomaticParameterTuner.cpp.

00337 {
00338     m_optimizeBlendRMSE = enable;
00339 }

void AutomaticParameterTuner::setOptimizeProbeRmse ( bool  enable  ) 

For stochastic parameter tuner, to enable optimizing the calcRMSEonProbe()

Parameters:
enable Enable bit

Definition at line 326 of file AutomaticParameterTuner.cpp.

00327 {
00328     m_optimizeProbeRMSE = enable;
00329 }

void AutomaticParameterTuner::simpleStochasticParameterFinder ( double  minProbeImpro = 0.00002,
int  maxProbeEpochsWithoutImpro = 100,
double  minBlendImpro = 0.000001,
int  maxBlendEpochsWithoutImpro = 200,
double  stdDev = 0.1 
)

Starts the stochastic parameter tuner This tuner selects randomly a parameter and draw a new value with a normal distribution around the parameter value. Very simple tuninig algorithm.

Parameters:
minProbeImpro Minimal error improvement until break
maxProbeEpochsWithoutImpro Number of epochs without improvement for break
minBlendImpro Minimal error(calcRMSEonBlend()) until break
maxBlendEpochsWithoutImpro Number of epochs without improvement for break (on blend)
stdDev The standard deviation of the normal(gauss) distribution from the new param value

Definition at line 151 of file AutomaticParameterTuner.cpp.

00152 {
00153     vector<double> bestDoubleParam;
00154     vector<int> bestIntParam;
00155 
00156     bestDoubleParam.resize ( m_doubleParam.size() );
00157     for ( int i=0; i < m_doubleParam.size(); i++ )
00158         bestDoubleParam[i] = *m_doubleParam[i];
00159     bestIntParam.resize ( m_intParam.size() );
00160     for ( int i=0; i < m_intParam.size(); i++ )
00161         bestIntParam[i] = *m_intParam[i];
00162 
00163 
00164     int cnt=0;
00165     double bestRmse = 10.0;
00166 
00167     if ( m_optimizeProbeRMSE == true )
00168     {
00169         while ( cnt < maxProbeEpochsWithoutImpro )
00170         {
00171             for ( int i=0; i < m_doubleParam.size(); i++ )
00172                 *m_doubleParam[i] = bestDoubleParam[i];
00173             for ( int i=0; i < m_intParam.size(); i++ )
00174                 *m_intParam[i] = bestIntParam[i];
00175 
00176             long ticks = clock();
00177             int sel = rand() % ( m_doubleParam.size() + m_intParam.size() );
00178 
00179             if ( sel < m_doubleParam.size() )
00180             {
00181                 *m_doubleParam[sel] = ( double ) NumericalTools::getNormRandomNumber ( bestDoubleParam[sel], max ( fabs ( bestDoubleParam[sel] ) * stdDev, 0.001 ) );
00182                 *m_doubleParam[sel] = NumericalTools::clipValue ( *m_doubleParam[sel], m_doubleMin[sel], m_doubleMax[sel] );
00183             }
00184             else
00185             {
00186                 sel -= m_doubleParam.size();
00187 
00188                 *m_intParam[sel] = ( int ) NumericalTools::getNormRandomNumber ( ( double ) bestIntParam[sel], max ( fabs ( ( double ) bestIntParam[sel] ) * stdDev, 1.0 ) );
00189 
00190                 if ( *m_intParam[sel] < m_intMin[sel] )
00191                     *m_intParam[sel] = m_intMin[sel];
00192                 if ( *m_intParam[sel] > m_intMax[sel] )
00193                     *m_intParam[sel] = m_intMax[sel];
00194             }
00195 
00196 
00197             double rmse = calcRMSEonProbe();
00198 
00199             if ( rmse < bestRmse )
00200             {
00201                 if ( bestRmse - rmse > minProbeImpro )
00202                 {
00203                     cout<<"*";
00204                     cnt=0;
00205                 }
00206 
00207                 bestRmse = rmse;
00208                 for ( int i=0; i < m_doubleParam.size(); i++ )
00209                     bestDoubleParam[i] = *m_doubleParam[i];
00210                 for ( int i=0; i < m_intParam.size(); i++ )
00211                     bestIntParam[i] = *m_intParam[i];
00212                 cout<<"* ";
00213             }
00214 
00215             ticks = clock() - ticks;
00216 
00217             cnt++;
00218 
00219             // output
00220             cout<< ( float ) ticks / ( float ) CLOCKS_PER_SEC<<" s | ERR: "<<rmse;
00221             for ( int i=0; i < m_doubleParam.size(); i++ )
00222                 cout<<" | "<<m_doubleName[i]<<": "<<*m_doubleParam[i];
00223             for ( int i=0; i < m_intParam.size(); i++ )
00224                 cout<<" | "<<m_intName[i]<<": "<<*m_intParam[i];
00225             cout<<endl;
00226         }
00227 
00228         for ( int i=0; i < m_doubleParam.size(); i++ )
00229             *m_doubleParam[i] = bestDoubleParam[i];
00230         for ( int i=0; i < m_intParam.size(); i++ )
00231             *m_intParam[i] = bestIntParam[i];
00232 
00233         cout<<"bestParameters on Probe: ERR: "<<bestRmse<<" ";
00234         for ( int i=0; i < m_doubleParam.size(); i++ )
00235             cout<<" | "<<m_doubleName[i]<<": "<<*m_doubleParam[i];
00236         for ( int i=0; i < m_intParam.size(); i++ )
00237             cout<<" | "<<m_intName[i]<<": "<<*m_intParam[i];
00238         cout<<endl;
00239     }
00240 
00241 
00242 
00243     // ============== find the best Parameters on the blend =================
00244     cnt=0;
00245     bestRmse = 10.0;
00246     if ( m_optimizeBlendRMSE == true )
00247     {
00248         while ( cnt < maxBlendEpochsWithoutImpro )
00249         {
00250             for ( int i=0; i < m_doubleParam.size(); i++ )
00251                 *m_doubleParam[i] = bestDoubleParam[i];
00252             for ( int i=0; i < m_intParam.size(); i++ )
00253                 *m_intParam[i] = bestIntParam[i];
00254 
00255             long ticks = clock();
00256             int sel = rand() % ( m_doubleParam.size() + m_intParam.size() );
00257 
00258             if ( sel < m_doubleParam.size() )
00259             {
00260                 *m_doubleParam[sel] = ( double ) NumericalTools::getNormRandomNumber ( bestDoubleParam[sel], max ( fabs ( bestDoubleParam[sel] ) * stdDev, 0.001 ) );
00261                 *m_doubleParam[sel] = NumericalTools::clipValue ( *m_doubleParam[sel], m_doubleMin[sel], m_doubleMax[sel] );
00262             }
00263             else
00264             {
00265                 sel -= m_doubleParam.size();
00266 
00267                 *m_intParam[sel] = ( int ) NumericalTools::getNormRandomNumber ( ( double ) bestIntParam[sel], max ( fabs ( ( double ) bestIntParam[sel] ) * stdDev, 1.0 ) );
00268 
00269                 if ( *m_intParam[sel] < m_intMin[sel] )
00270                     *m_intParam[sel] = m_intMin[sel];
00271                 if ( *m_intParam[sel] > m_intMax[sel] )
00272                     *m_intParam[sel] = m_intMax[sel];
00273             }
00274 
00275 
00276             double rmse = calcRMSEonBlend();
00277 
00278             if ( rmse < bestRmse )
00279             {
00280                 if ( bestRmse - rmse > minBlendImpro )
00281                 {
00282                     cout<<"*";
00283                     cnt=0;
00284                 }
00285 
00286                 bestRmse = rmse;
00287                 for ( int i=0; i < m_doubleParam.size(); i++ )
00288                     bestDoubleParam[i] = *m_doubleParam[i];
00289                 for ( int i=0; i < m_intParam.size(); i++ )
00290                     bestIntParam[i] = *m_intParam[i];
00291                 cout<<"* ";
00292             }
00293 
00294             ticks = clock() - ticks;
00295 
00296             cnt++;
00297 
00298             // output
00299             cout<< ( float ) ticks / ( float ) CLOCKS_PER_SEC<<" s | ERR: "<<rmse;
00300             for ( int i=0; i < m_doubleParam.size(); i++ )
00301                 cout<<" | "<<m_doubleName[i]<<": "<<*m_doubleParam[i];
00302             for ( int i=0; i < m_intParam.size(); i++ )
00303                 cout<<" | "<<m_intName[i]<<": "<<*m_intParam[i];
00304             cout<<endl;
00305         }
00306 
00307         for ( int i=0; i < m_doubleParam.size(); i++ )
00308             *m_doubleParam[i] = bestDoubleParam[i];
00309         for ( int i=0; i < m_intParam.size(); i++ )
00310             *m_intParam[i] = bestIntParam[i];
00311 
00312         cout<<"bestParameters on Blend: ERR: "<<bestRmse<<" ";
00313         for ( int i=0; i < m_doubleParam.size(); i++ )
00314             cout<<" | "<<m_doubleName[i]<<": "<<*m_doubleParam[i];
00315         for ( int i=0; i < m_intParam.size(); i++ )
00316             cout<<" | "<<m_intName[i]<<": "<<*m_intParam[i];
00317         cout<<endl;
00318     }
00319 }


The documentation for this class was generated from the following files:

Generated on Tue Jan 26 09:21:03 2010 for ELF by  doxygen 1.5.8