Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Algorithms.GradientDescent/3.3/Lbfgs.cs @ 9409

Last change on this file since 9409 was 9409, checked in by gkronber, 12 years ago

#1423:

  • removed setting of name and description in LBFGS constructor
  • changed names of placeholder operators in LBFGS
  • added parameter for gradient checking.
File size: 10.6 KB
Line 
1
2#region License Information
3/* HeuristicLab
4 * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
5 *
6 * This file is part of HeuristicLab.
7 *
8 * HeuristicLab is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * HeuristicLab is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
20 */
21#endregion
22
23using System;
24using HeuristicLab.Common;
25using HeuristicLab.Core;
26using HeuristicLab.Data;
27using HeuristicLab.Encodings.RealVectorEncoding;
28using HeuristicLab.Operators;
29using HeuristicLab.Optimization;
30using HeuristicLab.Parameters;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32using HeuristicLab.Random;
33
34namespace HeuristicLab.Algorithms.GradientDescent {
35  /// <summary>
36  /// Limited-Memory BFGS optimization algorithm.
37  /// </summary>
38  [Item("LM-BFGS", "The limited-memory BFGS (Broyden–Fletcher–Goldfarb–Shanno) optimization algorithm.")]
39  [Creatable("Algorithms")]
40  [StorableClass]
41  public sealed class LbfgsAlgorithm : HeuristicOptimizationEngineAlgorithm, IStorableContent {
42    public override Type ProblemType {
43      get { return typeof(ISingleObjectiveHeuristicOptimizationProblem); }
44    }
45
46    public new ISingleObjectiveHeuristicOptimizationProblem Problem {
47      get { return (ISingleObjectiveHeuristicOptimizationProblem)base.Problem; }
48      set { base.Problem = value; }
49    }
50
51    public string Filename { get; set; }
52
53    private const string MaxIterationsParameterName = "MaxIterations";
54    private const string ApproximateGradientsParameterName = "ApproximateGradients";
55    private const string SeedParameterName = "Seed";
56    private const string SetSeedRandomlyParameterName = "SetSeedRandomly";
57    private const string GradientCheckStepSizeParameterName = "GradientCheckStepSize";
58
59    #region parameter properties
60    public IValueParameter<IntValue> MaxIterationsParameter {
61      get { return (IValueParameter<IntValue>)Parameters[MaxIterationsParameterName]; }
62    }
63    public IValueParameter<IntValue> SeedParameter {
64      get { return (IValueParameter<IntValue>)Parameters[SeedParameterName]; }
65    }
66    public IValueParameter<BoolValue> SetSeedRandomlyParameter {
67      get { return (IValueParameter<BoolValue>)Parameters[SetSeedRandomlyParameterName]; }
68    }
69    public IValueParameter<DoubleValue> GradientStepSizeParameter {
70      get { return (IValueParameter<DoubleValue>)Parameters[GradientCheckStepSizeParameterName]; }
71    }
72    #endregion
73    #region properties
74    public int MaxIterations {
75      set { MaxIterationsParameter.Value.Value = value; }
76      get { return MaxIterationsParameter.Value.Value; }
77    }
78    public int Seed { get { return SeedParameter.Value.Value; } set { SeedParameter.Value.Value = value; } }
79    public bool SetSeedRandomly { get { return SetSeedRandomlyParameter.Value.Value; } set { SetSeedRandomlyParameter.Value.Value = value; } }
80    #endregion
81
82    [Storable]
83    private LbfgsInitializer initializer;
84    [Storable]
85    private LbfgsMakeStep makeStep;
86    [Storable]
87    private LbfgsUpdateResults updateResults;
88    [Storable]
89    private LbfgsAnalyzer analyzer;
90    [Storable]
91    private LbfgsAnalyzer finalAnalyzer;
92    [Storable]
93    private Placeholder solutionCreator;
94    [Storable]
95    private Placeholder evaluator;
96
97    [StorableConstructor]
98    private LbfgsAlgorithm(bool deserializing) : base(deserializing) { }
99    private LbfgsAlgorithm(LbfgsAlgorithm original, Cloner cloner)
100      : base(original, cloner) {
101      initializer = cloner.Clone(original.initializer);
102      makeStep = cloner.Clone(original.makeStep);
103      updateResults = cloner.Clone(original.updateResults);
104      analyzer = cloner.Clone(original.analyzer);
105      finalAnalyzer = cloner.Clone(original.finalAnalyzer);
106      solutionCreator = cloner.Clone(original.solutionCreator);
107      evaluator = cloner.Clone(original.evaluator);
108      RegisterEvents();
109    }
110    public LbfgsAlgorithm()
111      : base() {
112
113      Parameters.Add(new ValueParameter<IntValue>(MaxIterationsParameterName, "The maximal number of iterations for.", new IntValue(20)));
114      Parameters.Add(new ValueParameter<IntValue>(SeedParameterName, "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
115      Parameters.Add(new ValueParameter<BoolValue>(SetSeedRandomlyParameterName, "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
116      Parameters.Add(new ValueParameter<BoolValue>(ApproximateGradientsParameterName, "Indicates that gradients should be approximated.", new BoolValue(true)));
117      Parameters.Add(new OptionalValueParameter<DoubleValue>(GradientCheckStepSizeParameterName, "Step size for the gradient check (should be used for debugging the gradient calculation only)."));
118      // these parameter should not be changed usually
119      Parameters[ApproximateGradientsParameterName].Hidden = true;
120      Parameters[GradientCheckStepSizeParameterName].Hidden = true;
121
122      var randomCreator = new RandomCreator();
123      solutionCreator = new Placeholder();
124      initializer = new LbfgsInitializer();
125      makeStep = new LbfgsMakeStep();
126      var branch = new ConditionalBranch();
127      evaluator = new Placeholder();
128      updateResults = new LbfgsUpdateResults();
129      analyzer = new LbfgsAnalyzer();
130      finalAnalyzer = new LbfgsAnalyzer();
131
132      OperatorGraph.InitialOperator = randomCreator;
133
134      randomCreator.SeedParameter.ActualName = SeedParameterName;
135      randomCreator.SeedParameter.Value = null;
136      randomCreator.SetSeedRandomlyParameter.ActualName = SetSeedRandomlyParameterName;
137      randomCreator.SetSeedRandomlyParameter.Value = null;
138      randomCreator.Successor = solutionCreator;
139
140      solutionCreator.Name = "(Solution Creator)";
141      solutionCreator.Successor = initializer;
142
143      initializer.IterationsParameter.ActualName = MaxIterationsParameterName;
144      initializer.ApproximateGradientsParameter.ActualName = ApproximateGradientsParameterName;
145      initializer.Successor = makeStep;
146
147      makeStep.StateParameter.ActualName = initializer.StateParameter.Name;
148      makeStep.Successor = branch;
149
150      branch.ConditionParameter.ActualName = makeStep.TerminationCriterionParameter.Name;
151      branch.FalseBranch = evaluator;
152      branch.TrueBranch = finalAnalyzer;
153
154      evaluator.Name = "(Evaluator)";
155      evaluator.Successor = updateResults;
156
157      updateResults.StateParameter.ActualName = initializer.StateParameter.Name;
158      updateResults.ApproximateGradientsParameter.ActualName = ApproximateGradientsParameterName;
159      updateResults.Successor = analyzer;
160
161      analyzer.StateParameter.ActualName = initializer.StateParameter.Name;
162      analyzer.Successor = makeStep;
163
164      finalAnalyzer.PointsTableParameter.ActualName = analyzer.PointsTableParameter.ActualName;
165      finalAnalyzer.QualityGradientsTableParameter.ActualName = analyzer.QualityGradientsTableParameter.ActualName;
166      finalAnalyzer.QualitiesTableParameter.ActualName = analyzer.QualitiesTableParameter.ActualName;
167    }
168
169    [StorableHook(HookType.AfterDeserialization)]
170    private void AfterDeserialization() {
171      RegisterEvents();
172    }
173
174    public override IDeepCloneable Clone(Cloner cloner) {
175      return new LbfgsAlgorithm(this, cloner);
176    }
177
178    #region events
179    private void RegisterEvents() {
180      if (Problem != null) {
181        RegisterSolutionCreatorEvents();
182        RegisterEvaluatorEvents();
183      }
184    }
185
186    protected override void OnProblemChanged() {
187      base.OnProblemChanged();
188      if (Problem != null) {
189        RegisterEvents();
190        solutionCreator.OperatorParameter.ActualName = Problem.SolutionCreatorParameter.Name;
191        evaluator.OperatorParameter.ActualName = Problem.EvaluatorParameter.Name;
192      }
193    }
194
195    protected override void Problem_SolutionCreatorChanged(object sender, EventArgs e) {
196      base.Problem_SolutionCreatorChanged(sender, e);
197      RegisterSolutionCreatorEvents();
198      ParameterizeOperators();
199    }
200
201    protected override void Problem_EvaluatorChanged(object sender, EventArgs e) {
202      base.Problem_EvaluatorChanged(sender, e);
203      RegisterEvaluatorEvents();
204      ParameterizeOperators();
205    }
206
207    private void RegisterSolutionCreatorEvents() {
208      var realVectorCreator = Problem.SolutionCreator as IRealVectorCreator;
209      // ignore if we have a different kind of problem
210      if (realVectorCreator != null) {
211        realVectorCreator.RealVectorParameter.ActualNameChanged += (sender, args) => ParameterizeOperators();
212      }
213    }
214
215    private void RegisterEvaluatorEvents() {
216      Problem.Evaluator.QualityParameter.ActualNameChanged += (sender, args) => ParameterizeOperators();
217    }
218    #endregion
219
220    protected override void OnStarted() {
221      var realVectorCreator = Problem.SolutionCreator as IRealVectorCreator;
222      // must catch the case that user loaded an unsupported problem
223      if (realVectorCreator == null)
224        throw new InvalidOperationException("LM-BFGS only works with problems using a real-value encoding.");
225      base.OnStarted();
226    }
227
228    public override void Prepare() {
229      if (Problem != null) base.Prepare();
230    }
231
232    private void ParameterizeOperators() {
233      var realVectorCreator = Problem.SolutionCreator as IRealVectorCreator;
234      // ignore if we have a different kind of problem
235      if (realVectorCreator != null) {
236        var realVectorParameterName = realVectorCreator.RealVectorParameter.ActualName;
237        initializer.PointParameter.ActualName = realVectorParameterName;
238        makeStep.PointParameter.ActualName = realVectorParameterName;
239        analyzer.PointParameter.ActualName = realVectorParameterName;
240        finalAnalyzer.PointParameter.ActualName = realVectorParameterName;
241      }
242
243      var qualityParameterName = Problem.Evaluator.QualityParameter.ActualName;
244      updateResults.QualityParameter.ActualName = qualityParameterName;
245      analyzer.QualityParameter.ActualName = qualityParameterName;
246      finalAnalyzer.QualityParameter.ActualName = qualityParameterName;
247    }
248  }
249}
Note: See TracBrowser for help on using the repository browser.