00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "freSPSAOptimizerController.h"
00023 #include "freExceptions.h"
00024
00025 namespace FREE
00026 {
00027
00031
00032
00033
00034 DefineParameterMacro(SPSAOptimizerController,MinimumNumberOfIteration,"MinimumNumberOfIteration","Minimum number of iteration the optimizer will compute.");
00035 DefineParameterMacro(SPSAOptimizerController,MaximumNumberOfIteration,"MaximumNumberOfIteration","Maximum number of iterations the optimizer will compute before terminating, even if no convergence is achieved.");
00036 DefineParameterMacro(SPSAOptimizerController,a,"a","a is a factor that scales the estimated gradient before substracting it from the current position to achive the next position. Should be non-negative. Can be estimated via GuessParameters.");
00037 DefineParameterMacro(SPSAOptimizerController,A,"A","A is a non-negative coefficient used to calculate the a of the next iteration step. Can be estimated via GuessParameters.");
00038 DefineParameterMacro(SPSAOptimizerController,c,"c","c is a factor that scales the pertubation vector, which will be added to the current position to estimate the gradient");
00039 DefineParameterMacro(SPSAOptimizerController,Alpha,"Alpha","Alpha is used to calculate the gain sequence a k.");
00040 DefineParameterMacro(SPSAOptimizerController,Gamma,"Gamma","Gamma is used to calculate the gain sequence c k.");
00041 DefineParameterMacro(SPSAOptimizerController,NumberOfPertubations,"NumberOfPertubations","Number of pertubations used to estimate the gradient at the current position.");
00042 DefineParameterMacro(SPSAOptimizerController,ConvergenceDecayRate,"ConvergenceDecayRate","The convergence value (magnitute of the gradient) will be multiplied every iteration step with this factor.");
00043 DefineParameterMacro(SPSAOptimizerController,Tolerance,"Tolerance","if the convergence value is below the tolerance the optimizer will terminate.");
00044 DefineParameterMacro(SPSAOptimizerController,GuessParameters,"GuessParameters","Indicates if the parameters a and A will be guessed (in this case any given value for both will be ignored).");
00045 DefineParameterMacro(SPSAOptimizerController,Guess_GradientEstimates,"Guess_GradientEstimates","Number of gradient estimations used to guess the parameters.");
00046 DefineParameterMacro(SPSAOptimizerController,Guess_InitialStepSize,"Guess_InitialStepSize","Maximum of the absolute values of the parameter update.");
00047
00048 SPSAOptimizerController::
00049 SPSAOptimizerController()
00050 {
00051
00052 this->UpdateControllerID(ControllerID::SPSAOptimizerController);
00053 this->m_Description = "Optimizes by using a SPSA optimizer with Brent line search.";
00054
00055 };
00056
00057 void
00058 SPSAOptimizerController::
00059 GenerateProfile(CtrlProfile::ControllerProfile& profile,
00060 const SessionComponentCache* pComponentCache,
00061 bool bRegardOldSetup) const
00062 {
00063 Superclass::GenerateProfile(profile,pComponentCache,bRegardOldSetup);
00064
00065
00066 profile.Parameters().AddParameter(cParam_MinimumNumberOfIteration,Parameter::PVTULong,cParamDsc_MinimumNumberOfIteration,1,"10",-1,true);
00067 profile.Parameters().AddParameter(cParam_MaximumNumberOfIteration,Parameter::PVTULong,cParamDsc_MaximumNumberOfIteration,1,"100",-1,true);
00068 profile.Parameters().AddParameter(cParam_a,Parameter::PVTDouble,cParamDsc_a,1,"1.0",-1,true);
00069 profile.Parameters().AddParameter(cParam_A,Parameter::PVTDouble,cParamDsc_A,1,"10",-1,true);
00070 profile.Parameters().AddParameter(cParam_c,Parameter::PVTDouble,cParamDsc_c,1,"1.0",-1,true);
00071 profile.Parameters().AddParameter(cParam_Alpha,Parameter::PVTDouble,cParamDsc_Alpha,1,"0.602",-1,true);
00072 profile.Parameters().AddParameter(cParam_Gamma,Parameter::PVTDouble,cParamDsc_Gamma,1,"0.101",-1,true);
00073 profile.Parameters().AddParameter(cParam_NumberOfPertubations,Parameter::PVTLong,cParamDsc_NumberOfPertubations,1,"1",-1,true);
00074 profile.Parameters().AddParameter(cParam_ConvergenceDecayRate,Parameter::PVTDouble,cParamDsc_ConvergenceDecayRate,1,"0.9",-1,true);
00075 profile.Parameters().AddParameter(cParam_Tolerance,Parameter::PVTDouble,cParamDsc_Tolerance,1,"1e-06",-1,true);
00076 profile.Parameters().AddParameter(cParam_GuessParameters,Parameter::PVTBool,cParamDsc_GuessParameters,1,"false",1);
00077 profile.Parameters().AddParameter(cParam_Guess_GradientEstimates,Parameter::PVTULong,cParamDsc_Guess_GradientEstimates,1,"2",-1,true);
00078 profile.Parameters().AddParameter(cParam_Guess_InitialStepSize,Parameter::PVTDouble,cParamDsc_Guess_InitialStepSize,1,"1.0",-1,true);
00079 };
00080
00081 void
00082 SPSAOptimizerController::
00083 ActualizeMainComponent(ComponentType* pMainComponent,
00084 SessionComponentCache* pComponentCache, SessionInfo* pSessionInfo,
00085 const unsigned int& iActLevel) const
00086 {
00087 unsigned long lMinIterations;
00088 unsigned long lMaxIterations;
00089 double da;
00090 double dA;
00091 double dc;
00092 double dAlpha;
00093 double dGamma;
00094 long lNrOfPertubations;
00095 double dDecayRate;
00096 double dTolerance;
00097
00098 try
00099 {
00100 SessionAccessor::GetParameterValue(pComponentCache,cParam_MinimumNumberOfIteration,lMinIterations,0,iActLevel,true);
00101 SessionAccessor::GetParameterValue(pComponentCache,cParam_MaximumNumberOfIteration,lMaxIterations,0,iActLevel,true);
00102 SessionAccessor::GetParameterValue(pComponentCache,cParam_a,da,0,iActLevel,true);
00103 SessionAccessor::GetParameterValue(pComponentCache,cParam_A,dA,0,iActLevel,true);
00104 SessionAccessor::GetParameterValue(pComponentCache,cParam_c,dc,0,iActLevel,true);
00105 SessionAccessor::GetParameterValue(pComponentCache,cParam_Alpha,dAlpha,0,iActLevel,true);
00106 SessionAccessor::GetParameterValue(pComponentCache,cParam_Gamma,dGamma,0,iActLevel,true);
00107 SessionAccessor::GetParameterValue(pComponentCache,cParam_NumberOfPertubations,lNrOfPertubations,0,iActLevel,true);
00108 SessionAccessor::GetParameterValue(pComponentCache,cParam_ConvergenceDecayRate,dDecayRate,0,iActLevel,true);
00109 SessionAccessor::GetParameterValue(pComponentCache,cParam_Tolerance,dTolerance,0,iActLevel,true);
00110 }
00111 catchAllNPassMacro("Error while retrieving parameter values.");
00112
00113 ParameterArrayType scales = this->GetTransformScales(pComponentCache,iActLevel);
00114 pMainComponent->SetScales(scales);
00115
00116 pMainComponent->SetMinimumNumberOfIterations(lMinIterations);
00117 pMainComponent->SetMaximumNumberOfIterations(lMaxIterations);
00118 pMainComponent->Seta(da);
00119 pMainComponent->SetA(dA);
00120 pMainComponent->Setc(dc);
00121 pMainComponent->SetAlpha(dAlpha);
00122 pMainComponent->SetGamma(dGamma);
00123 pMainComponent->SetNumberOfPerturbations(lNrOfPertubations);
00124 pMainComponent->SetStateOfConvergenceDecayRate(dDecayRate);
00125 pMainComponent->SetTolerance(dTolerance);
00126
00127 Parameter::Pointer smpDirection = pComponentCache->GetParentCache()->Controller()->GetParameter(pComponentCache->GetParentCache(),OptimizerOwnerControllerInterface::cParam_MinimizeToOptimize);
00128 if (smpDirection.IsNull()) throwCtrlExceptionMacro("","Cannot retrieve optimization direction via optimizer owner. Parameter \"MinimizeToOptimize\" is unknown. Please ensure valid session and setup");
00129 bool bMinimize;
00130 smpDirection->GetParameterValue(bMinimize);
00131 pMainComponent->SetMaximize( !bMinimize);
00132 };
00133
00134 void
00135 SPSAOptimizerController::
00136 SetStatisticEntryMainComponent(StatisticEntry& rStatisticEntry,
00137 ComponentType* pMainComponent,
00138 SessionComponentCache* pMainComponentCache,
00139 SessionInfo* pSessionInfo,
00140 StatisticDictionary& rDictionary) const
00141 {
00142 Superclass::SetStatisticEntryMainComponent(rStatisticEntry,pMainComponent,
00143 pMainComponentCache,pSessionInfo,
00144 rDictionary);
00145
00146 std::string sName = "LearningRate";
00147 std::string sIDPath = pMainComponentCache->GetIDPath();
00148 StatisticValueDefinition* pEntry = rDictionary.GetValueDefinitionByName(sIDPath, sName);
00149
00150 if (!pEntry)
00151 {
00152 pEntry = rDictionary.AddValueDefinition(sIDPath,sName,"The current a_k");
00153 rDictionary.AddValueDefinition(sIDPath,"GradientMagnitude","GradientMagnitude of the latest computed gradient.");
00154 rDictionary.AddValueDefinition(sIDPath,"StateOfConvergence","Get the state of convergence in the last iteration. When the StateOfConvergence is lower than the Tolerance the optimization stops.");
00155 rDictionary.AddValueDefinition(sIDPath,"OptimizerValue","Value of the Optimizer");
00156 }
00157
00158 rStatisticEntry.AddValue(Convert::ToStr(pMainComponent->GetLearningRate()),pEntry->GetRefID());
00159 rStatisticEntry.AddValue(Convert::ToStr(pMainComponent->GetGradientMagnitude()),pEntry->GetRefID()+1);
00160 rStatisticEntry.AddValue(Convert::ToStr(pMainComponent->GetStateOfConvergence()),pEntry->GetRefID()+2);
00161 rStatisticEntry.AddValue(Convert::ToStr(pMainComponent->GetValue()),pEntry->GetRefID()+3);
00162 };
00163
00164 void
00165 SPSAOptimizerController::
00166 ActualizeFinalization(ComponentType* pMainComponent, SessionComponentCache* pComponentCache,
00167 SessionInfo* pSessionInfo, const unsigned int& iActLevel) const
00168 {
00169 if (!pComponentCache->SetupIsAssigned()) throwCtrlExceptionMacro("","Error. Cannot finalize component actualization; setup is missing in cache.");
00170 ComponentSetup* pComponentSetup = pComponentCache->Setup();
00171
00172
00173 bool bGuess;
00174 unsigned long lGuess_NrOfEstimates;
00175 double dGuess_StepSize;
00176
00177 try
00178 {
00179 SessionAccessor::GetParameterValue(pComponentCache,cParam_GuessParameters,bGuess);
00180 SessionAccessor::GetParameterValue(pComponentCache,cParam_Guess_GradientEstimates,lGuess_NrOfEstimates);
00181 SessionAccessor::GetParameterValue(pComponentCache,cParam_Guess_InitialStepSize,dGuess_StepSize);
00182 }
00183 catchAllNPassMacro("Error while retrieving parameter values.");
00184
00185 if (bGuess)
00186 {
00187 pMainComponent->GuessParameters(lGuess_NrOfEstimates,dGuess_StepSize);
00188 }
00189 };
00190
00191 SPSAOptimizerController::MeasuresType
00192 SPSAOptimizerController::
00193 GetCurrentValue(ComponentType* pOptimizer) const
00194 {
00195 MeasuresType values(1);
00196 values.Fill(pOptimizer->GetValue());
00197 return values;
00198 };
00199
00200 }