#include <AutomaticParameterTuner.h>
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 > ¶mVector) |
void | setCurrentParameter (const vector< double > ¶mVector) |
void | calcCenter (const vector< pair< double, vector< double > > > &simplexPoints, vector< double > ¢er) |
double | getReflectionPoint (const vector< double > ¢er, 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 |
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.
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] |
void AutomaticParameterTuner::addDoubleParameter | ( | double * | param, | |
string | name, | |||
double | min = -DBL_MAX , |
|||
double | max = DBL_MAX | |||
) |
Add a double parameter
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)
param | The pointer to the integer | |
name | The name (string) |
Definition at line 35 of file AutomaticParameterTuner.cpp.
void AutomaticParameterTuner::addIntegerParameter | ( | int * | param, | |
string | name, | |||
int | min = INT_MIN , |
|||
int | max = INT_MAX | |||
) |
Add an integer parameter
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
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
paramVector | references to the double paremeters |
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
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
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
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
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
Definition at line 785 of file AutomaticParameterTuner.cpp.
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
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
epochs | The maximal blend optimizing epochs |
Definition at line 775 of file AutomaticParameterTuner.cpp.
double AutomaticParameterTuner::getReflectionPoint | ( | const vector< double > & | center, | |
const vector< double > & | worstPoint, | |||
vector< double > & | reflectionPoint, | |||
double | alpha | |||
) | [protected] |
Returns the reflection point
center | the current center | |
worstPoint | the worst point | |
reflectionPoint | the reflection point | |
alpha | step size dependent parameter |
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
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
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
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
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
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
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)
en | Enable bit |
Definition at line 346 of file AutomaticParameterTuner.cpp.
void AutomaticParameterTuner::setOptimizeBlendRmse | ( | bool | enable | ) |
For stochastic parameter tuner, to enable optimizing the calcRMSEonBlend()
enable | Enable bit |
Definition at line 336 of file AutomaticParameterTuner.cpp.
void AutomaticParameterTuner::setOptimizeProbeRmse | ( | bool | enable | ) |
For stochastic parameter tuner, to enable optimizing the calcRMSEonProbe()
enable | Enable bit |
Definition at line 326 of file AutomaticParameterTuner.cpp.
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.
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 }