Changeset 16616


Ignore:
Timestamp:
02/20/19 07:43:25 (2 years ago)
Author:
gkronber
Message:

#2925 added crossover probability (important for multi-encoding in this case), re-added scaling of targets

Location:
branches/2925_AutoDiffForDynamicalModels
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Crossovers/SubtreeCrossover.cs

    r15583 r16616  
    4343    private const string MaximumSymbolicExpressionTreeLengthParameterName = "MaximumSymbolicExpressionTreeLength";
    4444    private const string MaximumSymbolicExpressionTreeDepthParameterName = "MaximumSymbolicExpressionTreeDepth";
     45    private const string CrossoverProbabilityParameterName = "CrossoverProbability";
    4546
    4647    #region Parameter Properties
     
    5354    public IValueLookupParameter<IntValue> MaximumSymbolicExpressionTreeDepthParameter {
    5455      get { return (IValueLookupParameter<IntValue>)Parameters[MaximumSymbolicExpressionTreeDepthParameterName]; }
     56    }
     57    public IValueParameter<PercentValue> CrossoverProbabilityParameter {
     58      get { return (IValueParameter<PercentValue>)Parameters[CrossoverProbabilityParameterName]; }
    5559    }
    5660    #endregion
     
    6468    public IntValue MaximumSymbolicExpressionTreeDepth {
    6569      get { return MaximumSymbolicExpressionTreeDepthParameter.ActualValue; }
     70    }
     71    public PercentValue CrossoverProbability {
     72      get { return CrossoverProbabilityParameter.Value; }
    6673    }
    6774    #endregion
     
    7481      Parameters.Add(new ValueLookupParameter<IntValue>(MaximumSymbolicExpressionTreeDepthParameterName, "The maximal depth of the symbolic expression tree (a tree with one node has depth = 0)."));
    7582      Parameters.Add(new ValueLookupParameter<PercentValue>(InternalCrossoverPointProbabilityParameterName, "The probability to select an internal crossover point (instead of a leaf node).", new PercentValue(0.9)));
     83      Parameters.Add(new ValueParameter<PercentValue>(CrossoverProbabilityParameterName, "The probability to apply crossover (default 100%).", new PercentValue(1)));
    7684    }
    7785
    7886    public override IDeepCloneable Clone(Cloner cloner) {
    7987      return new SubtreeCrossover(this, cloner);
     88    }
     89
     90    [StorableHook(HookType.AfterDeserialization)]
     91    private void AfterDeserialization() {
     92      if (!Parameters.ContainsKey(CrossoverProbabilityParameterName)) {
     93        Parameters.Add(new ValueParameter<PercentValue>(CrossoverProbabilityParameterName, "The probability to apply crossover (default 100%).", new PercentValue(1)));
     94      }
    8095    }
    8196
     
    8398      ISymbolicExpressionTree parent0, ISymbolicExpressionTree parent1) {
    8499      return Cross(random, parent0, parent1, InternalCrossoverPointProbability.Value,
    85         MaximumSymbolicExpressionTreeLength.Value, MaximumSymbolicExpressionTreeDepth.Value);
     100        MaximumSymbolicExpressionTreeLength.Value, MaximumSymbolicExpressionTreeDepth.Value, CrossoverProbability.Value);
    86101    }
    87102
    88103    public static ISymbolicExpressionTree Cross(IRandom random,
    89104      ISymbolicExpressionTree parent0, ISymbolicExpressionTree parent1,
    90       double internalCrossoverPointProbability, int maxTreeLength, int maxTreeDepth) {
     105      double internalCrossoverPointProbability, int maxTreeLength, int maxTreeDepth, double crossoverProbability = 1.0) {
     106      if (random.NextDouble() >= crossoverProbability) {
     107        return random.NextDouble() < 0.5 ? parent0 : parent1;
     108      }
     109
    91110      // select a random crossover point in the first parent
    92111      CutPoint crossoverPoint0;
  • branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/Problem.cs

    r16610 r16616  
    245245      nmse = OptimizeParameters(trees, problemData, targetVars, latentVariables, episodes, maxParameterOptIterations, pretunedParameters, numericIntegrationSteps, odeSolver,
    246246        out double[] optTheta);
     247      // var optTheta = pretunedParameters;
    247248
    248249      if (double.IsNaN(nmse) ||
     
    297298            alglib.minlmreport report;
    298299            var p = new double[initialTheta[treeIdx].Length];
    299             var lowerBounds = Enumerable.Repeat(-100.0, p.Length).ToArray();
    300             var upperBounds = Enumerable.Repeat(100.0, p.Length).ToArray();
     300            var lowerBounds = Enumerable.Repeat(-1000.0, p.Length).ToArray();
     301            var upperBounds = Enumerable.Repeat(1000.0, p.Length).ToArray();
    301302            Array.Copy(initialTheta[treeIdx], p, p.Length);
    302303            alglib.minlmcreatevj(targetValuesDiff.Count, p, out state);
    303304            alglib.minlmsetcond(state, 0.0, 0.0, 0.0, maxParameterOptIterations);
    304305            alglib.minlmsetbc(state, lowerBounds, upperBounds);
    305             // alglib.minlmsetgradientcheck(state, 1.0e-3);
     306#if DEBUG
     307            //alglib.minlmsetgradientcheck(state, 1.0e-7);
     308#endif
    306309            alglib.minlmoptimize(state, EvaluateObjectiveVector, EvaluateObjectiveVectorAndJacobian, null, myState);
    307310
    308311            alglib.minlmresults(state, out optTheta, out report);
    309             if (report.terminationtype < 0) { optTheta = initialTheta[treeIdx]; }
     312            if (report.terminationtype < 0) {
     313#if DEBUG
     314              if (report.terminationtype == -7) throw new InvalidProgramException("gradient calculation fail!");
     315#endif
     316              optTheta = initialTheta[treeIdx];
     317            }
    310318          } catch (alglib.alglibexception) {
    311319            optTheta = initialTheta[treeIdx];
     
    342350
    343351      if (initialTheta.Length > 0) {
    344         var lowerBounds = Enumerable.Repeat(-100.0, initialTheta.Length).ToArray();
    345         var upperBounds = Enumerable.Repeat(100.0, initialTheta.Length).ToArray();
     352        var lowerBounds = Enumerable.Repeat(-1000.0, initialTheta.Length).ToArray();
     353        var upperBounds = Enumerable.Repeat(1000.0, initialTheta.Length).ToArray();
    346354        try {
    347355          alglib.minlmstate state;
     
    350358          alglib.minlmsetbc(state, lowerBounds, upperBounds);
    351359          alglib.minlmsetcond(state, 0.0, 0.0, 0.0, maxParameterOptIterations);
    352           // alglib.minlmsetgradientcheck(state, 1.0e-3);
     360#if DEBUG         
     361          //alglib.minlmsetgradientcheck(state, 1.0e-7);
     362#endif
    353363          alglib.minlmoptimize(state, IntegrateAndEvaluateObjectiveVector, IntegrateAndEvaluateObjectiveVectorAndJacobian, null, myState);
    354364
     
    356366
    357367          if (report.terminationtype < 0) {
    358             // there was a problem: reset theta and evaluate for inital values
     368#if DEBUG
     369            if (report.terminationtype == -7) throw new InvalidProgramException("gradient calculation fail!");
     370#endif            // there was a problem: reset theta and evaluate for inital values
    359371            optTheta = initialTheta;
    360372          }
     
    397409          var pred = InterpretRec(tree.Root.GetSubtree(0).GetSubtree(0), nodeValueLookup);
    398410          var y = optimizationData.targetValues[treeIdx][trainIdx];
    399           fi[outputIdx++] = y - pred;
     411          fi[outputIdx++] = (y - pred) * optimizationData.inverseStandardDeviation[treeIdx];
    400412        }
    401413      }
     
    602614            var y = targetValues[colIdx][r];
    603615
    604             var res = (y - y_pred_f);
     616            var res = (y - y_pred_f) * optimizationData.inverseStandardDeviation[colIdx];
    605617            var ressq = res * res;
    606             f_i += ressq * optimizationData.inverseStandardDeviation[colIdx];
    607             g_i.Add(y_pred[colIdx].Item2.Scale(-2.0 * res * optimizationData.inverseStandardDeviation[colIdx]));
     618            f_i += ressq;
     619            g_i.Add(y_pred[colIdx].Item2.Scale(-2.0 * res));
    608620          }
    609621          seRow.Values.Add(f_i);
     
    858870
    859871        var flag = CVODES.CVodeInit(cvode_mem, f, 0.0, y);
    860         Debug.Assert(CVODES.CV_SUCCESS == flag);
     872        Assert(CVODES.CV_SUCCESS == flag);
    861873
    862874        double relTol = 1.0e-2;
    863875        double absTol = 1.0;
    864876        flag = CVODES.CVodeSStolerances(cvode_mem, relTol, absTol);  // TODO: probably need to adjust absTol per variable
    865         Debug.Assert(CVODES.CV_SUCCESS == flag);
     877        Assert(CVODES.CV_SUCCESS == flag);
    866878
    867879        A = CVODES.SUNDenseMatrix(numberOfEquations, numberOfEquations);
    868         Debug.Assert(A != IntPtr.Zero);
     880        Assert(A != IntPtr.Zero);
    869881
    870882        linearSolver = CVODES.SUNDenseLinearSolver(y, A);
    871         Debug.Assert(linearSolver != IntPtr.Zero);
     883        Assert(linearSolver != IntPtr.Zero);
    872884
    873885        flag = CVODES.CVDlsSetLinearSolver(cvode_mem, linearSolver, A);
    874         Debug.Assert(CVODES.CV_SUCCESS == flag);
     886        Assert(CVODES.CV_SUCCESS == flag);
    875887
    876888        flag = CVODES.CVDlsSetJacFn(cvode_mem, jac);
    877         Debug.Assert(CVODES.CV_SUCCESS == flag);
     889        Assert(CVODES.CV_SUCCESS == flag);
    878890
    879891        yS0 = CVODES.N_VCloneVectorArray_Serial(ns, y); // clone the output vector for each parameter
     
    889901
    890902        flag = CVODES.CVodeSensInit(cvode_mem, ns, CVODES.CV_SIMULTANEOUS, sensF, yS0);
    891         Debug.Assert(CVODES.CV_SUCCESS == flag);
     903        Assert(CVODES.CV_SUCCESS == flag);
    892904
    893905        flag = CVODES.CVodeSensEEtolerances(cvode_mem);
    894         Debug.Assert(CVODES.CV_SUCCESS == flag);
     906        Assert(CVODES.CV_SUCCESS == flag);
    895907
    896908        // make one forward integration step
     
    898910        flag = CVODES.CVode(cvode_mem, t, y, ref tout, CVODES.CV_NORMAL);
    899911        if (flag == CVODES.CV_SUCCESS) {
    900           Debug.Assert(t == tout);
     912          Assert(t == tout);
    901913
    902914          // get sensitivities
    903915          flag = CVODES.CVodeGetSens(cvode_mem, ref tout, yS0);
    904           Debug.Assert(CVODES.CV_SUCCESS == flag);
     916          Assert(CVODES.CV_SUCCESS == flag);
    905917
    906918          // update variableValues based on integration results
     
    11491161        return nodeValues.NodeValue(node);
    11501162      } else if (node.Symbol is Addition) {
    1151         Debug.Assert(node.SubtreeCount == 2);
     1163        Assert(node.SubtreeCount == 2);
    11521164        var f = InterpretRec(node.GetSubtree(0), nodeValues);
    11531165        var g = InterpretRec(node.GetSubtree(1), nodeValues);
    11541166        return f + g;
    11551167      } else if (node.Symbol is Multiplication) {
    1156         Debug.Assert(node.SubtreeCount == 2);
     1168        Assert(node.SubtreeCount == 2);
    11571169        var f = InterpretRec(node.GetSubtree(0), nodeValues);
    11581170        var g = InterpretRec(node.GetSubtree(1), nodeValues);
    11591171        return f * g;
    11601172      } else if (node.Symbol is Subtraction) {
    1161         Debug.Assert(node.SubtreeCount <= 2);
     1173        Assert(node.SubtreeCount <= 2);
    11621174        if (node.SubtreeCount == 1) {
    11631175          var f = InterpretRec(node.GetSubtree(0), nodeValues);
     
    11701182        }
    11711183      } else if (node.Symbol is Division) {
    1172         Debug.Assert(node.SubtreeCount <= 2);
     1184        Assert(node.SubtreeCount <= 2);
    11731185
    11741186        if (node.SubtreeCount == 1) {
     
    11921204        }
    11931205      } else if (node.Symbol is Sine) {
    1194         Debug.Assert(node.SubtreeCount == 1);
     1206        Assert(node.SubtreeCount == 1);
    11951207
    11961208        var f = InterpretRec(node.GetSubtree(0), nodeValues);
    11971209        return Math.Sin(f);
    11981210      } else if (node.Symbol is Cosine) {
    1199         Debug.Assert(node.SubtreeCount == 1);
     1211        Assert(node.SubtreeCount == 1);
    12001212
    12011213        var f = InterpretRec(node.GetSubtree(0), nodeValues);
    12021214        return Math.Cos(f);
    12031215      } else if (node.Symbol is Square) {
    1204         Debug.Assert(node.SubtreeCount == 1);
     1216        Assert(node.SubtreeCount == 1);
    12051217
    12061218        var f = InterpretRec(node.GetSubtree(0), nodeValues);
    12071219        return f * f;
    12081220      } else if (node.Symbol is Exponential) {
    1209         Debug.Assert(node.SubtreeCount == 1);
     1221        Assert(node.SubtreeCount == 1);
    12101222
    12111223        var f = InterpretRec(node.GetSubtree(0), nodeValues);
    12121224        return Math.Exp(f);
    12131225      } else if (node.Symbol is Logarithm) {
    1214         Debug.Assert(node.SubtreeCount == 1);
     1226        Assert(node.SubtreeCount == 1);
    12151227
    12161228        var f = InterpretRec(node.GetSubtree(0), nodeValues);
    12171229        return Math.Log(f);
    12181230      } else throw new NotSupportedException("unsupported symbol");
     1231    }
     1232
     1233    private static void Assert(bool cond) {
     1234#if DEBUG
     1235      if (!cond) throw new InvalidOperationException("Assertion failed");
     1236#endif
    12191237    }
    12201238
     
    12311249        dz = Vector.CreateNew(nodeValues.NodeGradient(node)); // original gradient vectors are never changed by evaluation
    12321250      } else if (node.Symbol is Addition) {
     1251
     1252        Assert(node.SubtreeCount == 2);
    12331253        InterpretRec(node.GetSubtree(0), nodeValues, out f, out df);
    12341254        InterpretRec(node.GetSubtree(1), nodeValues, out g, out dg);
     
    12361256        dz = df.Add(dg);
    12371257      } else if (node.Symbol is Multiplication) {
     1258
     1259        Assert(node.SubtreeCount == 2);
    12381260        InterpretRec(node.GetSubtree(0), nodeValues, out f, out df);
    12391261        InterpretRec(node.GetSubtree(1), nodeValues, out g, out dg);
     
    12421264
    12431265      } else if (node.Symbol is Subtraction) {
     1266
     1267        Assert(node.SubtreeCount <= 2);
    12441268        if (node.SubtreeCount == 1) {
    12451269          InterpretRec(node.GetSubtree(0), nodeValues, out f, out df);
     
    12541278
    12551279      } else if (node.Symbol is Division) {
     1280
     1281        Assert(node.SubtreeCount <= 2);
    12561282        if (node.SubtreeCount == 1) {
    12571283          InterpretRec(node.GetSubtree(0), nodeValues, out f, out df);
     
    12811307
    12821308      } else if (node.Symbol is Sine) {
     1309
     1310        Assert(node.SubtreeCount == 1);
    12831311        InterpretRec(node.GetSubtree(0), nodeValues, out f, out df);
    12841312        z = Math.Sin(f);
     
    12861314
    12871315      } else if (node.Symbol is Cosine) {
     1316
     1317        Assert(node.SubtreeCount == 1);
    12881318        InterpretRec(node.GetSubtree(0), nodeValues, out f, out df);
    12891319        z = Math.Cos(f);
    12901320        dz = df.Scale(-Math.Sin(f));
    12911321      } else if (node.Symbol is Square) {
     1322
     1323        Assert(node.SubtreeCount == 1);
    12921324        InterpretRec(node.GetSubtree(0), nodeValues, out f, out df);
    12931325        z = f * f;
    12941326        dz = df.Scale(2.0 * f);
    12951327      } else if (node.Symbol is Exponential) {
     1328
     1329        Assert(node.SubtreeCount == 1);
    12961330        InterpretRec(node.GetSubtree(0), nodeValues, out f, out df);
    12971331        z = Math.Exp(f);
    12981332        dz = df.Scale(Math.Exp(f));
    12991333      } else if (node.Symbol is Logarithm) {
     1334
     1335        Assert(node.SubtreeCount == 1);
    13001336        InterpretRec(node.GetSubtree(0), nodeValues, out f, out df);
    13011337        z = Math.Log(f);
     
    14431479        // make sure our multi-manipulator is the only manipulator
    14441480        e.Operators = new IOperator[] { multiManipulator }.Concat(filteredOperators);
     1481
     1482        // set the crossover probability to reduce likelihood that multiple trees are crossed at the same time
     1483        var subtreeCrossovers = e.Operators.OfType<SubtreeCrossover>();
     1484        foreach (var xover in subtreeCrossovers) {
     1485          xover.CrossoverProbability.Value = 0.3;
     1486        }
     1487
    14451488        encoding = encoding.Add(e); // only limit by length
    14461489      }
     
    14511494        // make sure our multi-manipulator is the only manipulator
    14521495        e.Operators = new IOperator[] { multiManipulator }.Concat(filteredOperators);
     1496
     1497        // set the crossover probability to reduce likelihood that multiple trees are crossed at the same time
     1498        var subtreeCrossovers = e.Operators.OfType<SubtreeCrossover>();
     1499        foreach (var xover in subtreeCrossovers) {
     1500          xover.CrossoverProbability.Value = 0.3;
     1501        }
     1502
    14531503        encoding = encoding.Add(e);
    14541504      }
     
    15891639        this.targetValues = targetValues;
    15901640        this.variables = inputVariables;
    1591         // if (targetValues != null) {
    1592         //   this.inverseStandardDeviation = new double[targetValues.Length];
    1593         //   for (int i = 0; i < targetValues.Length; i++) {
    1594         //     // calculate variance for each episode separately and calc the average
    1595         //     var epStartIdx = 0;
    1596         //     var stdevs = new List<double>();
    1597         //     foreach (var ep in episodes) {
    1598         //       var epValues = targetValues[i].Skip(epStartIdx).Take(ep.Size);
    1599         //       stdevs.Add(epValues.StandardDeviation());
    1600         //       epStartIdx += ep.Size;
    1601         //     }
    1602         //     inverseStandardDeviation[i] = 1.0 / stdevs.Average();
    1603         //   }
    1604         // } else
    1605         this.inverseStandardDeviation = Enumerable.Repeat(1.0, trees.Length).ToArray();
     1641        if (targetValues != null) {
     1642          this.inverseStandardDeviation = new double[targetValues.Length];
     1643          for (int i = 0; i < targetValues.Length; i++) {
     1644            // calculate variance for each episode separately and calc the average
     1645            var epStartIdx = 0;
     1646            var stdevs = new List<double>();
     1647            foreach (var ep in episodes) {
     1648              var epValues = targetValues[i].Skip(epStartIdx).Take(ep.Size);
     1649              stdevs.Add(epValues.StandardDeviation());
     1650              epStartIdx += ep.Size;
     1651            }
     1652            inverseStandardDeviation[i] = 1.0 / stdevs.Average();
     1653          }
     1654        } else
     1655          this.inverseStandardDeviation = Enumerable.Repeat(1.0, trees.Length).ToArray();
    16061656        this.episodes = episodes;
    16071657        this.numericIntegrationSteps = numericIntegrationSteps;
Note: See TracChangeset for help on using the changeset viewer.