-
Notifications
You must be signed in to change notification settings - Fork 135
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Jimmy adding iteration limit convergence criterion #1862
base: devel
Are you sure you want to change the base?
Changes from all commits
da0bce7
c65846a
f89b32e
2147152
6c7a518
cf470e2
ded72c9
ad33821
1509eb3
b3f1eba
0ad8779
d5a6751
5271959
01e50e1
1fff889
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -67,6 +67,12 @@ class GradientDescent(RavenSampled): | |
# TODO change in input space? | ||
'objective': r"""provides the maximum relative change in the objective function for convergence.""", | ||
'stepSize': r"""provides the maximum size in relative step size for convergence.""", | ||
'iterationLimit': r"""provides the maximum number of iterations at which the optimizer will terminate regardless of the status of any convergence criteria. | ||
Note that for Gradient Descent this counts only the optimization sweeps not the gradient evaluations. | ||
It is important to differentiate this from sampler'sinit <limit> node as the latter counts every model evaluation, | ||
hence, if n variables we will have 2n gradient evaluation if using centeral difference, number of iteration will be <limit>/(2n). If is less than the <iterationlimit> the GA will honor this lower limit. | ||
I.e., the termination (given all other covergence criteria are not met) will occur at min{<iterationLimit>, ceil(<limit>/gradient evaluations per variable/\# of variables) +1} | ||
For instance: if the \# of Variables is 2, and we perform 2 evaluations per variable for gradients, and if <limit> = 20, and <iterationLimit> is 10, the termination will occur at min{ceiling(20/(2*2))+1,10} = 6.""" | ||
} | ||
|
||
########################## | ||
|
@@ -149,7 +155,6 @@ def getInputSpecification(cls): | |
descr=r"""provides the number of consecutive times a functional constraint boundary can be explored | ||
for an acceptable sampling point before aborting search. Only apples if using a | ||
\xmlNode{Constraint}. \default{500}""")) | ||
|
||
for name, descr in cls.convergenceOptions.items(): | ||
conv.addSub(InputData.parameterInputFactory(name, contentType=InputTypes.FloatType, descr=descr)) | ||
terminate = InputData.parameterInputFactory('terminateFollowers', contentType=InputTypes.BoolType, | ||
|
@@ -265,6 +270,8 @@ def handleInput(self, paramInput): | |
elif sub.getName() == 'terminateFollowers': | ||
self._terminateFollowers = sub.value | ||
self._followerProximity = sub.parameterValues.get('proximity', 1e-2) | ||
elif sub.getName() == 'iterationLimit': | ||
self._convergenceCriteria['iterationLimit'] = sub.value | ||
elif sub.getName() == 'constraintExplorationLimit': | ||
self._functionalConstraintExplorationLimit = sub.value | ||
else: | ||
|
@@ -619,6 +626,7 @@ def _checkAcceptability(self, traj, opt, optVal, info): | |
# if this is an opt point rerun, accept it without checking. | ||
elif self._acceptRerun[traj]: | ||
acceptable = 'rerun' | ||
self.incrementIteration | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. does this line do anything? Did you mean |
||
self._acceptRerun[traj] = False | ||
self._stepRecommendations[traj] = 'shrink' # FIXME how much do we really want this? | ||
# check if same point | ||
|
@@ -790,6 +798,13 @@ def _checkConvGradient(self, traj): | |
|
||
return converged | ||
|
||
def _checkConvIterationLimit(self,traj): | ||
converged = self.getIteration(traj) >= self._convergenceCriteria['iterationLimit'] | ||
self.raiseADebug(self.convFormat.format(name='iterationLimit', | ||
conv=str(converged), | ||
got=int(self.getIteration(traj)), | ||
req=int(self._convergenceCriteria['iterationLimit']))) | ||
return converged | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. newline after |
||
def _checkConvStepSize(self, traj): | ||
""" | ||
Checks the step size for convergence | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -231,7 +231,7 @@ def localGenerateInput(self, model, inp): | |
self.inputInfo['batchMode'] = False | ||
for _ in range(self.batch): | ||
inputInfo = {'SampledVarsPb':{}, 'batchMode':self.inputInfo['batchMode']} # ,'prefix': str(self.batchId)+'_'+str(i) | ||
if self.counter == self.limit + 1: | ||
if self.getIteration(all(self._activeTraj)) == self.limit + 1: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not familiar with what if all(self.getIteration(self._activeTraj) == self.limit + 1) perhaps? |
||
break | ||
# get point from stack | ||
point, info = self._submissionQueue.popleft() | ||
|
@@ -560,6 +560,8 @@ def _resolveNewOptPoint(self, traj, rlz, optVal, info): | |
# nothing else to do but wait for the grad points to be collected | ||
elif acceptable == 'rejected': | ||
self._rejectOptPoint(traj, info, old) | ||
if self.printTag == 'GradientDescent': | ||
self.__stepCounter[traj] -= 1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this concerns me; are we not counting rejected steps as iterations now? This seems like it will create indexing problems and logistical mismatches. Help me understand why I'm wrong about that. |
||
elif acceptable == 'rerun': | ||
# update the most recently obtained opt value for the rerun point | ||
# NOTE we do this because if we got "lucky" in an opt point evaluation, we can get stuck | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
<?xml version="1.0" ?> | ||
<Simulation verbosity="debug"> | ||
<TestInfo> | ||
<name>framework/Optimizers.ConvergeObjective</name> | ||
<author>talbpaul</author> | ||
<created>2020-01-29</created> | ||
<classesTested>Optimizer</classesTested> | ||
<description> | ||
Extending on the Basic test, this test converges on change in objective function instead of | ||
number of samples. | ||
</description> | ||
<analytic> | ||
This test uses Beale's function, which is documented in the analytic tests documentation under | ||
the Optimizer functions section. | ||
</analytic> | ||
</TestInfo> | ||
|
||
<RunInfo> | ||
<WorkingDir>ConvergeIterationLimit</WorkingDir> | ||
<Sequence>optimize, print</Sequence> | ||
</RunInfo> | ||
|
||
<Steps> | ||
<MultiRun name="optimize"> | ||
<Input class="DataObjects" type="PointSet">placeholder</Input> | ||
<Model class="Models" type="ExternalModel">beale</Model> | ||
<Optimizer class="Optimizers" type="SPSA">opter</Optimizer> | ||
<SolutionExport class="DataObjects" type="PointSet">opt_export</SolutionExport> | ||
<Output class="DataObjects" type="PointSet">optOut</Output> | ||
</MultiRun> | ||
<IOStep name="print"> | ||
<Input class="DataObjects" type="PointSet">opt_export</Input> | ||
<Output class="OutStreams" type="Print">opt_export</Output> | ||
</IOStep> | ||
</Steps> | ||
|
||
<Distributions> | ||
<Uniform name='beale_dist'> | ||
<lowerBound>-4.5</lowerBound> | ||
<upperBound>4.5</upperBound> | ||
</Uniform> | ||
</Distributions> | ||
|
||
<Optimizers> | ||
<GradientDescent name="opter"> | ||
<objective>ans</objective> | ||
<variable name="x"> | ||
<distribution>beale_dist</distribution> | ||
<initial>-2</initial> | ||
</variable> | ||
<variable name="y"> | ||
<distribution>beale_dist</distribution> | ||
<initial>-2</initial> | ||
</variable> | ||
<TargetEvaluation class="DataObjects" type="PointSet">optOut</TargetEvaluation> | ||
<samplerInit> | ||
<limit>100</limit> | ||
<initialSeed>42</initialSeed> | ||
<writeSteps>every</writeSteps> | ||
</samplerInit> | ||
<gradient> | ||
<FiniteDifference/> | ||
</gradient> | ||
<stepSize> | ||
<GradientHistory> | ||
<growthFactor>1.25</growthFactor> | ||
<shrinkFactor>1.5</shrinkFactor> | ||
</GradientHistory> | ||
</stepSize> | ||
<acceptance> | ||
<Strict/> | ||
</acceptance> | ||
<convergence> | ||
<iterationLimit>10</iterationLimit> | ||
<gradient>1e-4</gradient> | ||
<objective>1e-4</objective> | ||
<stepSize>1e-12</stepSize> | ||
</convergence> | ||
</GradientDescent> | ||
</Optimizers> | ||
|
||
<Models> | ||
<ExternalModel ModuleToLoad="../../../framework/AnalyticModels/optimizing/beale" name="beale" subType=""> | ||
<variables>x,y,ans</variables> | ||
</ExternalModel> | ||
</Models> | ||
|
||
<DataObjects> | ||
<PointSet name="placeholder"/> | ||
<PointSet name="optOut"> | ||
<Input>x,y</Input> | ||
<Output>ans</Output> | ||
</PointSet> | ||
<PointSet name="opt_export"> | ||
<Input>trajID</Input> | ||
<Output>x,y,ans,stepSize,iteration,accepted,conv_iterationLimit,conv_gradient,conv_samePoint,conv_objective</Output> | ||
</PointSet> | ||
</DataObjects> | ||
|
||
<OutStreams> | ||
<Print name="optOut"> | ||
<type>csv</type> | ||
<source>optOut</source> | ||
</Print> | ||
<Print name="opt_export"> | ||
<type>csv</type> | ||
<source>opt_export</source> | ||
<clusterLabel>trajID</clusterLabel> | ||
</Print> | ||
</OutStreams> | ||
|
||
</Simulation> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,38 +8,38 @@ x,y,ans,stepSize,iteration,accepted,conv_gradient | |
2.1431640625,0.5,1.15860859692,0.1220703125,6.0,accepted,0.0 | ||
3.51645507813,0.5,0.420926728435,0.152587890625,7.0,accepted,0.0 | ||
1.79984130859,0.5,2.27310108344,0.190734863281,8.0,rejected,0.0 | ||
3.51645507813,0.5,0.420926728435,0.190734863281,9.0,rerun,0.0 | ||
2.37204589844,0.5,0.622296276884,0.127156575521,10.0,rejected,0.0 | ||
3.51645507813,0.5,0.420926728435,0.127156575521,11.0,rerun,0.0 | ||
2.753515625,0.5,0.0958782696724,0.0847710503472,12.0,accepted,0.0 | ||
3.70718994141,0.5,0.789248108373,0.105963812934,13.0,rejected,0.0 | ||
2.753515625,0.5,0.0958782696724,0.105963812934,14.0,rerun,0.0 | ||
3.3892985026,0.5,0.239170089642,0.070642541956,15.0,rejected,0.0 | ||
2.753515625,0.5,0.0958782696724,0.070642541956,16.0,rerun,0.0 | ||
3.17737087674,0.5,0.049648487802,0.0470950279707,17.0,accepted,0.0 | ||
2.64755181207,0.5,0.196034253796,0.0588687849633,18.0,rejected,0.0 | ||
3.17737087674,0.5,0.049648487802,0.0588687849633,19.0,rerun,0.0 | ||
2.82415816696,0.5,0.0487961777355,0.0392458566422,20.0,accepted,0.0 | ||
3.26567405418,0.5,0.111388328275,0.0490573208028,21.0,rejected,0.0 | ||
2.82415816696,0.5,0.0487961777355,0.0490573208028,22.0,rerun,0.0 | ||
3.11850209177,0.5,0.0221612081439,0.0327048805352,23.0,accepted,0.0 | ||
2.75057218575,0.5,0.0981818388529,0.040881100669,24.0,rejected,0.0 | ||
3.11850209177,0.5,0.0221612081439,0.040881100669,25.0,rerun,0.0 | ||
2.87321548776,0.5,0.0253672744839,0.0272540671127,26.0,rejected,0.0 | ||
3.11850209177,0.5,0.0221612081439,0.0272540671127,27.0,rerun,0.0 | ||
2.9549776891,0.5,0.00319887275602,0.0181693780751,28.0,accepted,0.0 | ||
3.15938319244,0.5,0.0400891125832,0.0227117225939,29.0,rejected,0.0 | ||
2.9549776891,0.5,0.00319887275602,0.0227117225939,30.0,rerun,0.0 | ||
3.09124802466,0.5,0.0131397875381,0.0151411483959,31.0,rejected,0.0 | ||
2.9549776891,0.5,0.00319887275602,0.0151411483959,32.0,rerun,0.0 | ||
3.04582457947,0.5,0.00331389219477,0.0100940989306,33.0,rejected,0.0 | ||
2.9549776891,0.5,0.00319887275602,0.0100940989306,34.0,rerun,0.0 | ||
3.01554228268,0.5,0.000381215900671,0.00672939928708,35.0,accepted,0.0 | ||
2.9398365407,0.5,0.0057122472706,0.00841174910885,36.0,rejected,0.0 | ||
3.01554228268,0.5,0.000381215900671,0.00841174910885,37.0,rerun,0.0 | ||
2.96507178803,0.5,0.00192528092425,0.00560783273923,38.0,rejected,0.0 | ||
3.01554228268,0.5,0.000381215900671,0.00560783273923,39.0,rerun,0.0 | ||
2.98189528625,0.5,0.000517278854294,0.00373855515949,40.0,rejected,0.0 | ||
3.01554228268,0.5,0.000381215900671,0.00373855515949,41.0,rerun,0.0 | ||
2.99311095172,0.5,7.4896212526e-05,0.00249237010632,42.0,accepted,0.0 | ||
2.99311095172,0.5,7.4896212526e-05,0.00249237010632,42.0,final,0.0 | ||
3.51645507813,0.5,0.420926728435,0.190734863281,8.0,rerun,0.0 | ||
2.37204589844,0.5,0.622296276884,0.127156575521,9.0,rejected,0.0 | ||
3.51645507813,0.5,0.420926728435,0.127156575521,9.0,rerun,0.0 | ||
2.753515625,0.5,0.0958782696724,0.0847710503472,10.0,accepted,0.0 | ||
3.70718994141,0.5,0.789248108373,0.105963812934,11.0,rejected,0.0 | ||
2.753515625,0.5,0.0958782696724,0.105963812934,11.0,rerun,0.0 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see the duplicate step numbers here, I'm struggling to resolve that, unless we want to consider a reject and subsequent rerun as part of the same step, in which case the user input example model run count is only accurate if there are no rejected points. |
||
3.3892985026,0.5,0.239170089642,0.070642541956,12.0,rejected,0.0 | ||
2.753515625,0.5,0.0958782696724,0.070642541956,12.0,rerun,0.0 | ||
3.17737087674,0.5,0.049648487802,0.0470950279707,13.0,accepted,0.0 | ||
2.64755181207,0.5,0.196034253796,0.0588687849633,14.0,rejected,0.0 | ||
3.17737087674,0.5,0.049648487802,0.0588687849633,14.0,rerun,0.0 | ||
2.82415816696,0.5,0.0487961777355,0.0392458566422,15.0,accepted,0.0 | ||
3.26567405418,0.5,0.111388328275,0.0490573208028,16.0,rejected,0.0 | ||
2.82415816696,0.5,0.0487961777355,0.0490573208028,16.0,rerun,0.0 | ||
3.11850209177,0.5,0.0221612081439,0.0327048805352,17.0,accepted,0.0 | ||
2.75057218575,0.5,0.0981818388529,0.040881100669,18.0,rejected,0.0 | ||
3.11850209177,0.5,0.0221612081439,0.040881100669,18.0,rerun,0.0 | ||
2.87321548776,0.5,0.0253672744839,0.0272540671127,19.0,rejected,0.0 | ||
3.11850209177,0.5,0.0221612081439,0.0272540671127,19.0,rerun,0.0 | ||
2.9549776891,0.5,0.00319887275602,0.0181693780751,20.0,accepted,0.0 | ||
3.15938319244,0.5,0.0400891125832,0.0227117225939,21.0,rejected,0.0 | ||
2.9549776891,0.5,0.00319887275602,0.0227117225939,21.0,rerun,0.0 | ||
3.09124802466,0.5,0.0131397875381,0.0151411483959,22.0,rejected,0.0 | ||
2.9549776891,0.5,0.00319887275602,0.0151411483959,22.0,rerun,0.0 | ||
3.04582457947,0.5,0.00331389219477,0.0100940989306,23.0,rejected,0.0 | ||
2.9549776891,0.5,0.00319887275602,0.0100940989306,23.0,rerun,0.0 | ||
3.01554228268,0.5,0.000381215900671,0.00672939928708,24.0,accepted,0.0 | ||
2.9398365407,0.5,0.0057122472706,0.00841174910885,25.0,rejected,0.0 | ||
3.01554228268,0.5,0.000381215900671,0.00841174910885,25.0,rerun,0.0 | ||
2.96507178803,0.5,0.00192528092425,0.00560783273923,26.0,rejected,0.0 | ||
3.01554228268,0.5,0.000381215900671,0.00560783273923,26.0,rerun,0.0 | ||
2.98189528625,0.5,0.000517278854294,0.00373855515949,27.0,rejected,0.0 | ||
3.01554228268,0.5,0.000381215900671,0.00373855515949,27.0,rerun,0.0 | ||
2.99311095172,0.5,7.4896212526e-05,0.00249237010632,28.0,accepted,0.0 | ||
2.99311095172,0.5,7.4896212526e-05,0.00249237010632,28.0,final,0.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some light editing, I suggest:
Is this default correct, or is there a default iteration limit?