Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/MultiLayerPerceptronRegression.cs @ 2570

Last change on this file since 2570 was 2570, checked in by gkronber, 14 years ago

Renamed methods in MultiLayerPerceptronRegression. #751.

File size: 19.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using System.Text;
26using HeuristicLab.Core;
27using System.Xml;
28using System.Diagnostics;
29using HeuristicLab.DataAnalysis;
30using HeuristicLab.Data;
31using HeuristicLab.Modeling;
32using HeuristicLab.Operators;
33using HeuristicLab.Random;
34using HeuristicLab.Selection;
35using HeuristicLab.Operators.Programmable;
36
37namespace HeuristicLab.ArtificialNeuralNetworks {
38  public class MultiLayerPerceptronRegression : ItemBase, IEditable, IAlgorithm {
39
40    public virtual string Name { get { return "MultiLayerPerceptronRegression"; } }
41    public virtual string Description { get { return "TODO"; } }
42
43    private IEngine engine;
44    public virtual IEngine Engine {
45      get { return engine; }
46    }
47
48    public virtual Dataset Dataset {
49      get { return ProblemInjector.GetVariableValue<Dataset>("Dataset", null, false); }
50      set { ProblemInjector.GetVariable("Dataset").Value = value; }
51    }
52
53    public virtual string TargetVariable {
54      get { return ProblemInjector.GetVariableValue<StringData>("TargetVariable", null, false).Data; }
55      set { ProblemInjector.GetVariableValue<StringData>("TargetVariable", null, false).Data = value; }
56    }
57
58    public virtual IOperator ProblemInjector {
59      get {
60        IOperator main = GetMainOperator();
61        CombinedOperator probInjector = (CombinedOperator)main.SubOperators[2];
62        return probInjector.OperatorGraph.InitialOperator.SubOperators[0];
63      }
64      set {
65        IOperator main = GetMainOperator();
66        CombinedOperator probInjector = (CombinedOperator)main.SubOperators[2];
67        probInjector.OperatorGraph.InitialOperator.RemoveSubOperator(0);
68        probInjector.OperatorGraph.InitialOperator.AddSubOperator(value, 0);
69      }
70    }
71    public IEnumerable<string> AllowedVariables {
72      get {
73        ItemList<StringData> allowedVariables = ProblemInjector.GetVariableValue<ItemList<StringData>>("AllowedFeatures", null, false);
74        return allowedVariables.Select(x => x.Data);
75      }
76      set {
77        ItemList<StringData> allowedVariables = ProblemInjector.GetVariableValue<ItemList<StringData>>("AllowedFeatures", null, false);
78        foreach (string x in value) allowedVariables.Add(new StringData(x));
79      }
80    }
81
82    public int TrainingSamplesStart {
83      get { return ProblemInjector.GetVariableValue<IntData>("TrainingSamplesStart", null, false).Data; }
84      set { ProblemInjector.GetVariableValue<IntData>("TrainingSamplesStart", null, false).Data = value; }
85    }
86
87    public int TrainingSamplesEnd {
88      get { return ProblemInjector.GetVariableValue<IntData>("TrainingSamplesEnd", null, false).Data; }
89      set { ProblemInjector.GetVariableValue<IntData>("TrainingSamplesEnd", null, false).Data = value; }
90    }
91
92    public int ValidationSamplesStart {
93      get { return ProblemInjector.GetVariableValue<IntData>("ValidationSamplesStart", null, false).Data; }
94      set { ProblemInjector.GetVariableValue<IntData>("ValidationSamplesStart", null, false).Data = value; }
95    }
96
97    public int ValidationSamplesEnd {
98      get { return ProblemInjector.GetVariableValue<IntData>("ValidationSamplesEnd", null, false).Data; }
99      set { ProblemInjector.GetVariableValue<IntData>("ValidationSamplesEnd", null, false).Data = value; }
100    }
101
102    public int TestSamplesStart {
103      get { return ProblemInjector.GetVariableValue<IntData>("TestSamplesStart", null, false).Data; }
104      set { ProblemInjector.GetVariableValue<IntData>("TestSamplesStart", null, false).Data = value; }
105    }
106
107    public int TestSamplesEnd {
108      get { return ProblemInjector.GetVariableValue<IntData>("TestSamplesEnd", null, false).Data; }
109      set { ProblemInjector.GetVariableValue<IntData>("TestSamplesEnd", null, false).Data = value; }
110    }
111
112    public IntArrayData NumberOfHiddenNodesList {
113      get { return GetVariableInjector().GetVariable("NumberOfHiddenNodesList").GetValue<IntArrayData>(); }
114      set { GetVariableInjector().GetVariable("NumberOfHiddenNodesList").Value = value; }
115    }
116
117    public int MaxNumberOfHiddenNodesListIndex {
118      get { return GetVariableInjector().GetVariable("MaxNumberOfHiddenNodesIndex").GetValue<IntData>().Data; }
119      set { GetVariableInjector().GetVariable("MaxNumberOfHiddenNodesIndex").GetValue<IntData>().Data = value; }
120    }
121
122    public virtual IAnalyzerModel Model {
123      get {
124        if (!engine.Terminated) throw new InvalidOperationException("The algorithm is still running. Wait until the algorithm is terminated to retrieve the result.");
125        IScope bestModelScope = engine.GlobalScope;
126        return CreateMlpModel(bestModelScope);
127      }
128    }
129
130    public MultiLayerPerceptronRegression() {
131      engine = new SequentialEngine.SequentialEngine();
132      CombinedOperator algo = CreateAlgorithm();
133      engine.OperatorGraph.AddOperator(algo);
134      engine.OperatorGraph.InitialOperator = algo;
135      MaxNumberOfHiddenNodesListIndex = NumberOfHiddenNodesList.Data.Length;
136    }
137
138    protected virtual CombinedOperator CreateAlgorithm() {
139      CombinedOperator algo = new CombinedOperator();
140      SequentialProcessor seq = new SequentialProcessor();
141      algo.Name = Name;
142      seq.Name = Name;
143
144      IOperator globalInjector = CreateGlobalInjector();
145
146      IOperator mainLoop = CreateMainLoop();
147
148      seq.AddSubOperator(globalInjector);
149      seq.AddSubOperator(new RandomInjector());
150      seq.AddSubOperator(CreateProblemInjector());
151      seq.AddSubOperator(mainLoop);
152      seq.AddSubOperator(CreatePostProcessingOperator());
153
154      algo.OperatorGraph.InitialOperator = seq;
155      algo.OperatorGraph.AddOperator(seq);
156
157      return algo;
158    }
159
160    private IOperator CreateMainLoop() {
161      SequentialProcessor seq = new SequentialProcessor();
162
163      #region initial solution
164      SubScopesCreater modelScopeCreator = new SubScopesCreater();
165      modelScopeCreator.GetVariableInfo("SubScopes").Local = true;
166      modelScopeCreator.AddVariable(new HeuristicLab.Core.Variable("SubScopes", new IntData(1)));
167      seq.AddSubOperator(modelScopeCreator);
168
169      SequentialSubScopesProcessor seqSubScopesProc = new SequentialSubScopesProcessor();
170      IOperator modelProcessor = CreateModelProcessor();
171
172      seqSubScopesProc.AddSubOperator(modelProcessor);
173      seq.AddSubOperator(seqSubScopesProc);
174      #endregion
175
176
177      Counter nHiddenNodesCounter = new Counter();
178      nHiddenNodesCounter.GetVariableInfo("Value").ActualName = "NumberOfHiddenNodesIndex";
179      nHiddenNodesCounter.Name = "NumberOfHiddenNodesIndexCounter";
180
181      LessThanComparator comparator = new LessThanComparator();
182      comparator.Name = "NumberOfHiddenNodesIndexComparator";
183      comparator.GetVariableInfo("LeftSide").ActualName = "NumberOfHiddenNodesIndex";
184      comparator.GetVariableInfo("RightSide").ActualName = "MaxNumberOfHiddenNodesIndex";
185      comparator.GetVariableInfo("Result").ActualName = "RepeatNumberOfHiddenNodesIndexLoop";
186
187      ConditionalBranch branch = new ConditionalBranch();
188      branch.Name = "IfValidNumberOfHiddenNodesIndex";
189      branch.GetVariableInfo("Condition").ActualName = "RepeatNumberOfHiddenNodesIndexLoop";
190
191
192
193      // build loop
194      SequentialProcessor loop = new SequentialProcessor();
195      loop.Name = "HiddenNodesLoop";
196
197      #region selection of better solution
198
199      loop.AddSubOperator(modelScopeCreator);
200      SequentialSubScopesProcessor subScopesProcessor = new SequentialSubScopesProcessor();
201      loop.AddSubOperator(subScopesProcessor);
202      subScopesProcessor.AddSubOperator(new EmptyOperator());
203      subScopesProcessor.AddSubOperator(CreateModelProcessor());
204
205      Sorter sorter = new Sorter();
206      sorter.GetVariableInfo("Value").ActualName = "ValidationQuality";
207      sorter.GetVariableInfo("Descending").Local = true;
208      sorter.AddVariable(new Variable("Descending", new BoolData(false)));
209      loop.AddSubOperator(sorter);
210
211      LeftSelector selector = new LeftSelector();
212      selector.GetVariableInfo("Selected").Local = true;
213      selector.AddVariable(new Variable("Selected", new IntData(1)));
214      loop.AddSubOperator(selector);
215
216      RightReducer reducer = new RightReducer();
217      loop.AddSubOperator(reducer);
218      #endregion
219
220      loop.AddSubOperator(nHiddenNodesCounter);
221      loop.AddSubOperator(comparator);
222
223      branch.AddSubOperator(loop);
224      loop.AddSubOperator(branch);
225
226
227      seq.AddSubOperator(loop);
228      return seq;
229    }
230
231    private IOperator CreateModelProcessor() {
232      SequentialProcessor modelProcessor = new SequentialProcessor();
233      modelProcessor.AddSubOperator(CreateSetNextParameterValueOperator("NumberOfHiddenNodes"));
234
235      MultiLayerPerceptronRegressionOperator trainingOperator = new MultiLayerPerceptronRegressionOperator();
236      trainingOperator.GetVariableInfo("NumberOfHiddenLayerNeurons").ActualName = "NumberOfHiddenNodes";
237      trainingOperator.GetVariableInfo("SamplesStart").ActualName = "ActualTrainingSamplesStart";
238      trainingOperator.GetVariableInfo("SamplesEnd").ActualName = "ActualTrainingSamplesEnd";
239
240      modelProcessor.AddSubOperator(trainingOperator);
241      CombinedOperator trainingEvaluator = (CombinedOperator)CreateEvaluator("ActualTraining");
242      trainingEvaluator.OperatorGraph.InitialOperator.SubOperators[1].GetVariableInfo("MSE").ActualName = "Quality";
243      modelProcessor.AddSubOperator(trainingEvaluator);
244      modelProcessor.AddSubOperator(CreateEvaluator("Validation"));
245
246      DataCollector collector = new DataCollector();
247      collector.GetVariableInfo("Values").ActualName = "Log";
248      ((ItemList<StringData>)collector.GetVariable("VariableNames").Value).Add(new StringData("NumberOfHiddenNodes"));
249      ((ItemList<StringData>)collector.GetVariable("VariableNames").Value).Add(new StringData("ValidationQuality"));
250      modelProcessor.AddSubOperator(collector);
251      return modelProcessor;
252    }
253
254    protected virtual IOperator CreateEvaluator(string p) {
255      CombinedOperator op = new CombinedOperator();
256      op.Name = p + "Evaluator";
257      SequentialProcessor seqProc = new SequentialProcessor();
258
259      MultiLayerPerceptronEvaluator evaluator = new MultiLayerPerceptronEvaluator();
260      evaluator.Name = p + "SimpleEvaluator";
261      evaluator.GetVariableInfo("SamplesStart").ActualName = p + "SamplesStart";
262      evaluator.GetVariableInfo("SamplesEnd").ActualName = p + "SamplesEnd";
263      evaluator.GetVariableInfo("Values").ActualName = p + "Values";
264      SimpleMSEEvaluator mseEvaluator = new SimpleMSEEvaluator();
265      mseEvaluator.Name = p + "MseEvaluator";
266      mseEvaluator.GetVariableInfo("Values").ActualName = p + "Values";
267      mseEvaluator.GetVariableInfo("MSE").ActualName = p + "Quality";
268      SimpleR2Evaluator r2Evaluator = new SimpleR2Evaluator();
269      r2Evaluator.Name = p + "R2Evaluator";
270      r2Evaluator.GetVariableInfo("Values").ActualName = p + "Values";
271      r2Evaluator.GetVariableInfo("R2").ActualName = p + "R2";
272      SimpleMeanAbsolutePercentageErrorEvaluator mapeEvaluator = new SimpleMeanAbsolutePercentageErrorEvaluator();
273      mapeEvaluator.Name = p + "MAPEEvaluator";
274      mapeEvaluator.GetVariableInfo("Values").ActualName = p + "Values";
275      mapeEvaluator.GetVariableInfo("MAPE").ActualName = p + "MAPE";
276      SimpleMeanAbsolutePercentageOfRangeErrorEvaluator mapreEvaluator = new SimpleMeanAbsolutePercentageOfRangeErrorEvaluator();
277      mapreEvaluator.Name = p + "MAPREEvaluator";
278      mapreEvaluator.GetVariableInfo("Values").ActualName = p + "Values";
279      mapreEvaluator.GetVariableInfo("MAPRE").ActualName = p + "MAPRE";
280      SimpleVarianceAccountedForEvaluator vafEvaluator = new SimpleVarianceAccountedForEvaluator();
281      vafEvaluator.Name = p + "VAFEvaluator";
282      vafEvaluator.GetVariableInfo("Values").ActualName = p + "Values";
283      vafEvaluator.GetVariableInfo("VAF").ActualName = p + "VAF";
284
285      seqProc.AddSubOperator(evaluator);
286      seqProc.AddSubOperator(mseEvaluator);
287      seqProc.AddSubOperator(r2Evaluator);
288      seqProc.AddSubOperator(mapeEvaluator);
289      seqProc.AddSubOperator(mapreEvaluator);
290      seqProc.AddSubOperator(vafEvaluator);
291
292      op.OperatorGraph.AddOperator(seqProc);
293      op.OperatorGraph.InitialOperator = seqProc;
294      return op;
295    }
296
297    private IOperator CreateSetNextParameterValueOperator(string paramName) {
298      ProgrammableOperator progOp = new ProgrammableOperator();
299      progOp.Name = "SetNext" + paramName;
300      progOp.RemoveVariableInfo("Result");
301      progOp.AddVariableInfo(new VariableInfo("Value", "Value", typeof(IntData), VariableKind.New));
302      progOp.AddVariableInfo(new VariableInfo("ValueIndex", "ValueIndex", typeof(IntData), VariableKind.In));
303      progOp.AddVariableInfo(new VariableInfo("ValueList", "ValueList", typeof(IntArrayData), VariableKind.In));
304      progOp.Code =
305@"
306Value.Data = ValueList.Data[ValueIndex.Data];
307";
308
309      progOp.GetVariableInfo("Value").ActualName = paramName;
310      progOp.GetVariableInfo("ValueIndex").ActualName = paramName + "Index";
311      progOp.GetVariableInfo("ValueList").ActualName = paramName + "List";
312      return progOp;
313    }
314
315
316    protected virtual IOperator CreateProblemInjector() {
317      return DefaultRegressionOperators.CreateProblemInjector();
318    }
319
320    protected virtual VariableInjector CreateGlobalInjector() {
321      VariableInjector injector = new VariableInjector();
322
323      injector.AddVariable(new HeuristicLab.Core.Variable("MaxNumberOfTrainingSamples", new IntData(4000)));
324      injector.AddVariable(new HeuristicLab.Core.Variable("PunishmentFactor", new DoubleData(1000)));
325      injector.AddVariable(new HeuristicLab.Core.Variable("NumberOfHiddenNodesIndex", new IntData(0)));
326      injector.AddVariable(new HeuristicLab.Core.Variable("MaxNumberOfHiddenNodesIndex", new IntData(0)));
327      injector.AddVariable(new HeuristicLab.Core.Variable("NumberOfHiddenNodesList", new IntArrayData(new int[] { 2, 4, 8, 16, 32, 64, 128 })));
328      injector.AddVariable(new HeuristicLab.Core.Variable("Log", new ItemList()));
329      return injector;
330    }
331
332    protected virtual IOperator CreatePostProcessingOperator() {
333      CombinedOperator op = new CombinedOperator();
334      op.Name = "Model Analyzer";
335
336      SequentialSubScopesProcessor seqSubScopesProc = new SequentialSubScopesProcessor();
337      SequentialProcessor seq = new SequentialProcessor();
338      seqSubScopesProc.AddSubOperator(seq);
339
340      #region simple evaluators
341      MultiLayerPerceptronEvaluator trainingEvaluator = new MultiLayerPerceptronEvaluator();
342      trainingEvaluator.GetVariableInfo("SamplesStart").ActualName = "TrainingSamplesStart";
343      trainingEvaluator.GetVariableInfo("SamplesEnd").ActualName = "TrainingSamplesEnd";
344      trainingEvaluator.GetVariableInfo("Values").ActualName = "TrainingValues";
345
346      MultiLayerPerceptronEvaluator testEvaluator = new MultiLayerPerceptronEvaluator();
347      testEvaluator.GetVariableInfo("SamplesStart").ActualName = "TestSamplesStart";
348      testEvaluator.GetVariableInfo("SamplesEnd").ActualName = "TestSamplesEnd";
349      testEvaluator.GetVariableInfo("Values").ActualName = "TestValues";
350
351      seq.AddSubOperator(trainingEvaluator);
352      seq.AddSubOperator(testEvaluator);
353      #endregion
354
355      #region variable impacts
356      // calculate and set variable impacts
357
358      PredictorBuilder predictorBuilder = new PredictorBuilder();
359
360      seq.AddSubOperator(predictorBuilder);
361      VariableQualityImpactCalculator qualityImpactCalculator = new VariableQualityImpactCalculator();
362      qualityImpactCalculator.GetVariableInfo("SamplesStart").ActualName = "TrainingSamplesStart";
363      qualityImpactCalculator.GetVariableInfo("SamplesEnd").ActualName = "TrainingSamplesEnd";
364
365      seq.AddSubOperator(qualityImpactCalculator);
366      #endregion
367
368      seq.AddSubOperator(CreateModelAnalyzerOperator());
369      op.OperatorGraph.AddOperator(seqSubScopesProc);
370      op.OperatorGraph.InitialOperator = seqSubScopesProc;
371      return op;
372    }
373
374    protected virtual IOperator CreateModelAnalyzerOperator() {
375      return DefaultRegressionOperators.CreatePostProcessingOperator();
376    }
377
378    protected virtual IAnalyzerModel CreateMlpModel(IScope bestModelScope) {
379      var model = new AnalyzerModel();
380      CreateSpecificMlpModel(bestModelScope, model);
381      #region variable impacts
382      ItemList qualityImpacts = bestModelScope.GetVariableValue<ItemList>(ModelingResult.VariableQualityImpact.ToString(), false);
383      foreach (ItemList row in qualityImpacts) {
384        string variableName = ((StringData)row[0]).Data;
385        double impact = ((DoubleData)row[1]).Data;
386        model.SetVariableResult(ModelingResult.VariableQualityImpact, variableName, impact);
387        model.AddInputVariable(variableName);
388      }
389      #endregion
390      return model;
391    }
392
393    protected virtual void CreateSpecificMlpModel(IScope bestModelScope, IAnalyzerModel model) {
394      DefaultRegressionOperators.PopulateAnalyzerModel(bestModelScope, model);
395    }
396
397    protected virtual IOperator GetMainOperator() {
398      CombinedOperator lr = (CombinedOperator)Engine.OperatorGraph.InitialOperator;
399      return lr.OperatorGraph.InitialOperator;
400    }
401
402    protected virtual IOperator GetVariableInjector() {
403      return GetMainOperator().SubOperators[0];
404    }
405
406    public override IView CreateView() {
407      return engine.CreateView();
408    }
409
410    #region IEditable Members
411
412    public virtual IEditor CreateEditor() {
413      return ((SequentialEngine.SequentialEngine)engine).CreateEditor();
414    }
415
416    #endregion
417
418    #region persistence
419    public override object Clone(IDictionary<Guid, object> clonedObjects) {
420      MultiLayerPerceptronRegression clone = (MultiLayerPerceptronRegression)base.Clone(clonedObjects);
421      clone.engine = (IEngine)Auxiliary.Clone(Engine, clonedObjects);
422      return clone;
423    }
424
425    public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
426      XmlNode node = base.GetXmlNode(name, document, persistedObjects);
427      node.AppendChild(PersistenceManager.Persist("Engine", engine, document, persistedObjects));
428      return node;
429    }
430
431    public override void Populate(XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
432      base.Populate(node, restoredObjects);
433      engine = (IEngine)PersistenceManager.Restore(node.SelectSingleNode("Engine"), restoredObjects);
434    }
435    #endregion
436  }
437}
Note: See TracBrowser for help on using the repository browser.