Changeset 16660 for branches/2925_AutoDiffForDynamicalModels
- Timestamp:
- 03/07/19 17:00:39 (6 years ago)
- Location:
- branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/Problem.cs
r16653 r16660 187 187 InitAllParameters(); 188 188 189 // TODO: UI hangs when selecting / deselecting input variables because the encoding is updated on each item190 189 // TODO: use training range as default training episode 191 // TODO: write back optimized parameters to solution?192 190 // TODO: optimization of starting values for latent variables in CVODES solver 193 191 // TODO: allow to specify the name for the time variable in the dataset and allow variable step-sizes 194 // TODO: check grammars (input variables) after cloning195 196 192 } 197 193 … … 235 231 string odeSolver) { 236 232 237 // extract constants from tree 238 var constantNodes = trees.Select(t => t.IterateNodesPrefix().OfType<ConstantTreeNode>().ToArray()).ToArray(); 233 // extract constants from trees (without trees for latent variables) 234 var targetVariableTrees = trees.Take(targetVars.Length).ToArray(); 235 var latentVariableTrees = trees.Skip(targetVars.Length).ToArray(); 236 var constantNodes = targetVariableTrees.Select(t => t.IterateNodesPrefix().OfType<ConstantTreeNode>().ToArray()).ToArray(); 239 237 var initialTheta = constantNodes.Select(nodes => nodes.Select(n => n.Value).ToArray()).ToArray(); 240 238 … … 242 240 double nmse = PreTuneParameters(trees, problemData, targetVars, latentVariables, random, episodes, maxParameterOptIterations, 243 241 initialTheta, out double[] pretunedParameters); 242 243 // extend parameter vector to include parameters for latent variable trees 244 pretunedParameters = pretunedParameters 245 .Concat(latentVariableTrees 246 .SelectMany(t => t.IterateNodesPrefix().OfType<ConstantTreeNode>().Select(n => n.Value))) 247 .ToArray(); 244 248 245 249 // optimize parameters using integration of f(x,y) to calculate y(t) … … 276 280 var maxTreeNmse = 100 * episodes.Sum(ep => ep.Size); 277 281 282 var targetTrees = trees.Take(targetVars.Length).ToArray(); 283 var latentTrees = trees.Take(latentVariables.Length).ToArray(); 284 285 { 286 // first calculate values of latent variables by integration 287 var inputVariables = targetVars.Concat(latentTrees.SelectMany(t => t.IterateNodesPrefix().OfType<VariableTreeNode>().Select(n => n.VariableName))).Except(latentVariables).Distinct(); 288 var myState = new OptimizationData(latentTrees, targetVars, inputVariables.ToArray(), problemData, null, episodes.ToArray(), 10, latentVariables, "HeuristicLab"); 289 290 var fi = new double[myState.rows.Length * targetVars.Length]; 291 var jac = new double[myState.rows.Length * targetVars.Length, myState.nodeValueLookup.ParameterCount]; 292 var latentValues = new double[myState.rows.Length, latentVariables.Length]; 293 Integrate(myState, fi, jac, latentValues); 294 295 // add integrated latent variables to dataset 296 var modifiedDataset = ((Dataset)problemData.Dataset).ToModifiable(); 297 foreach (var variable in latentVariables) { 298 modifiedDataset.AddVariable(variable, Enumerable.Repeat(0.0, modifiedDataset.Rows).ToList()); // empty column 299 } 300 int predIdx = 0; 301 foreach (var ep in episodes) { 302 for (int r = ep.Start; r < ep.End; r++) { 303 for (int latVarIdx = 0; latVarIdx < latentVariables.Length; latVarIdx++) { 304 modifiedDataset.SetVariableValue(latentValues[predIdx, latVarIdx], latentVariables[latVarIdx], r); 305 } 306 predIdx++; 307 } 308 } 309 310 problemData = new RegressionProblemData(modifiedDataset, problemData.AllowedInputVariables, problemData.TargetVariable); 311 } 278 312 // NOTE: the order of values in parameter matches prefix order of constant nodes in trees 279 for (int treeIdx = 0; treeIdx < t rees.Length; treeIdx++) {280 var t = t rees[treeIdx];313 for (int treeIdx = 0; treeIdx < targetTrees.Length; treeIdx++) { 314 var t = targetTrees[treeIdx]; 281 315 282 316 var targetValuesDiff = new List<double>(); … … 290 324 // data for input variables is assumed to be known 291 325 // input variables in pretuning are all target variables and all variable names that occur in the tree 292 var inputVariables = targetVars.Concat(t.IterateNodesPrefix().OfType<VariableTreeNode>().Select(n => n.VariableName)) ;326 var inputVariables = targetVars.Concat(t.IterateNodesPrefix().OfType<VariableTreeNode>().Select(n => n.VariableName)).Distinct(); 293 327 294 328 var myState = new OptimizationData(new[] { t }, … … 345 379 IEnumerable<IntRange> episodes, int maxParameterOptIterations, double[] initialTheta, int numericIntegrationSteps, string odeSolver, out double[] optTheta) { 346 380 var rowsForDataExtraction = episodes.SelectMany(e => Enumerable.Range(e.Start, e.Size)).ToArray(); 347 var targetValues = new double[t rees.Length][];348 for (int treeIdx = 0; treeIdx < t rees.Length; treeIdx++) {381 var targetValues = new double[targetVars.Length][]; 382 for (int treeIdx = 0; treeIdx < targetVars.Length; treeIdx++) { 349 383 var t = trees[treeIdx]; 350 384 … … 354 388 // data for input variables is assumed to be known 355 389 // input variables are all variable names that occur in the trees except for target variables (we assume that trees have been generated correctly) 356 var inputVariables = trees.SelectMany(t => t.IterateNodesPrefix().OfType<VariableTreeNode>().Select(n => n.VariableName)).Except(targetVars); 390 var inputVariables = trees.SelectMany(t => t.IterateNodesPrefix().OfType<VariableTreeNode>().Select(n => n.VariableName)) 391 .Except(targetVars) 392 .Except(latentVariables) 393 .Distinct(); 357 394 358 395 var myState = new OptimizationData(trees, targetVars, inputVariables.ToArray(), problemData, targetValues, episodes.ToArray(), numericIntegrationSteps, latentVariables, odeSolver); … … 495 532 nodeValueLookup.UpdateParamValues(x); 496 533 497 Integrate(optimizationData, fi, jac );534 Integrate(optimizationData, fi, jac, null); 498 535 var trees = optimizationData.trees; 499 536 500 537 // update result with error 501 538 for (int trainIdx = 0; trainIdx < rows.Length; trainIdx++) { 502 for (int i = 0; i < trees.Length; i++) {539 for (int i = 0; i < optimizationData.targetVariables.Length; i++) { 503 540 var tree = trees[i]; 504 541 var y = optimizationData.targetValues[i][trainIdx]; … … 583 620 // data for input variables is assumed to be known 584 621 // input variables are all variable names that occur in the trees except for target variables (we assume that trees have been generated correctly) 585 var inputVariables = trees.SelectMany(t => t.IterateNodesPrefix().OfType<VariableTreeNode>().Select(n => n.VariableName)).Except(targetVars); 622 var inputVariables = trees 623 .SelectMany(t => t.IterateNodesPrefix().OfType<VariableTreeNode>().Select(n => n.VariableName)) 624 .Except(targetVars) 625 .Except(latentVariables) 626 .Distinct(); 586 627 587 628 var optimizationData = new OptimizationData(trees, targetVars, inputVariables.ToArray(), problemData, null, TrainingEpisodes.ToArray(), NumericIntegrationSteps, latentVariables, OdeSolver); 588 var trainingPrediction = Integrate(optimizationData).ToArray();589 590 591 629 var numParams = optimizationData.nodeValueLookup.ParameterCount; 630 631 var fi = new double[optimizationData.rows.Length * targetVars.Length]; 632 var jac = new double[optimizationData.rows.Length * targetVars.Length, numParams]; 633 var latentValues = new double[optimizationData.rows.Length, latentVariables.Length]; 634 Integrate(optimizationData, fi, jac, latentValues); 635 636 592 637 // for target values and latent variables 593 638 var trainingRows = optimizationData.rows; … … 598 643 var trainingDataTable = new DataTable(targetVar + " prediction (training)"); 599 644 var actualValuesRow = new DataRow(targetVar, "The values of " + targetVar, problemData.Dataset.GetDoubleValues(targetVar, trainingRows)); 600 var predictedValuesRow = new DataRow(targetVar + " pred.", "Predicted values for " + targetVar, trainingPrediction.Select(arr => arr[colIdx].Item1).ToArray()); 645 var idx = Enumerable.Range(0, trainingRows.Length).Select(i => i * targetVars.Length + colIdx); 646 var pred = idx.Select(i => fi[i]); 647 var predictedValuesRow = new DataRow(targetVar + " pred.", "Predicted values for " + targetVar, pred.ToArray()); 601 648 trainingDataTable.Rows.Add(actualValuesRow); 602 649 trainingDataTable.Rows.Add(predictedValuesRow); 603 650 604 651 for (int paramIdx = 0; paramIdx < numParams; paramIdx++) { 605 var paramSensitivityRow = new DataRow($"∂{targetVar}/∂θ{paramIdx}", $"Sensitivities of parameter {paramIdx}", trainingPrediction.Select(arr => arr[colIdx].Item2[paramIdx]).ToArray());652 var paramSensitivityRow = new DataRow($"∂{targetVar}/∂θ{paramIdx}", $"Sensitivities of parameter {paramIdx}", idx.Select(i => jac[i, paramIdx]).ToArray()); 606 653 paramSensitivityRow.VisualProperties.SecondYAxis = true; 607 654 trainingDataTable.Rows.Add(paramSensitivityRow); … … 611 658 var latentVar = latentVariables[colIdx - targetVars.Length]; 612 659 var trainingDataTable = new DataTable(latentVar + " prediction (training)"); 613 var predictedValuesRow = new DataRow(latentVar + " pred.", "Predicted values for " + latentVar, trainingPrediction.Select(arr => arr[colIdx].Item1).ToArray()); 660 var idx = Enumerable.Range(0, trainingRows.Length); 661 var pred = idx.Select(i => latentValues[i, colIdx - targetVars.Length]); 662 var predictedValuesRow = new DataRow(latentVar + " pred.", "Predicted values for " + latentVar, pred.ToArray()); 614 663 var emptyRow = new DataRow(latentVar); 615 664 trainingDataTable.Rows.Add(emptyRow); … … 630 679 int r = 0; 631 680 632 foreach (var y_pred in trainingPrediction) {633 // calculate objective function gradient634 double f_i = 0.0;635 Vector g_i = Vector.CreateNew(new double[numParams]);636 for (int colIdx = 0; colIdx < targetVars.Length; colIdx++) {637 var y_pred_f = y_pred[colIdx].Item1;638 var y = targetValues[colIdx][r];639 640 var res = (y - y_pred_f) * optimizationData.inverseStandardDeviation[colIdx];641 var ressq = res * res;642 f_i += ressq;643 g_i.Add(y_pred[colIdx].Item2.Scale(-2.0 * res));644 }645 seRow.Values.Add(f_i);646 for (int j = 0; j < g_i.Length; j++) gradientRows[j].Values.Add(g_i[j]);647 r++;648 }649 results["Squared error and gradient"].Value = errorTable;681 // foreach (var y_pred in trainingPrediction) { 682 // // calculate objective function gradient 683 // double f_i = 0.0; 684 // Vector g_i = Vector.CreateNew(new double[numParams]); 685 // for (int colIdx = 0; colIdx < targetVars.Length; colIdx++) { 686 // var y_pred_f = y_pred[colIdx].Item1; 687 // var y = targetValues[colIdx][r]; 688 // 689 // var res = (y - y_pred_f) * optimizationData.inverseStandardDeviation[colIdx]; 690 // var ressq = res * res; 691 // f_i += ressq; 692 // g_i.Add(y_pred[colIdx].Item2.Scale(-2.0 * res)); 693 // } 694 // seRow.Values.Add(f_i); 695 // for (int j = 0; j < g_i.Length; j++) gradientRows[j].Values.Add(g_i[j]); 696 // r++; 697 // } 698 // results["Squared error and gradient"].Value = errorTable; 650 699 651 700 // TODO: DRY for training and test … … 667 716 668 717 } else { 669 var latentVar = latentVariables[colIdx - targetVars.Length];670 var testDataTable = new DataTable(latentVar + " prediction (test)");671 var predictedValuesRow = new DataRow(latentVar + " pred.", "Predicted values for " + latentVar, testPrediction.Select(arr => arr[colIdx].Item1).ToArray());672 var emptyRow = new DataRow(latentVar);673 testDataTable.Rows.Add(emptyRow);674 testDataTable.Rows.Add(predictedValuesRow);675 testList.Add(testDataTable);718 // var latentVar = latentVariables[colIdx - targetVars.Length]; 719 // var testDataTable = new DataTable(latentVar + " prediction (test)"); 720 // var predictedValuesRow = new DataRow(latentVar + " pred.", "Predicted values for " + latentVar, testPrediction.Select(arr => arr[colIdx].Item1).ToArray()); 721 // var emptyRow = new DataRow(latentVar); 722 // testDataTable.Rows.Add(emptyRow); 723 // testDataTable.Rows.Add(predictedValuesRow); 724 // testList.Add(testDataTable); 676 725 } 677 726 } … … 742 791 double[] fi = new double[n]; 743 792 double[,] jac = new double[n, d]; 744 Integrate(optimizationData, fi, jac );793 Integrate(optimizationData, fi, jac, null); 745 794 for (int i = 0; i < optimizationData.rows.Length; i++) { 746 795 var res = new Tuple<double, Vector>[nTargets]; … … 752 801 } 753 802 754 public static void Integrate(OptimizationData optimizationData, double[] fi, double[,] jac ) {803 public static void Integrate(OptimizationData optimizationData, double[] fi, double[,] jac, double[,] latentValues) { 755 804 var trees = optimizationData.trees; 756 805 var dataset = optimizationData.problemData.Dataset; … … 795 844 outputRowIdx++; 796 845 } 846 847 var latentValueRowIdx = 0; 848 var latentValueColIdx = 0; 849 foreach (var varName in latentVariables) { 850 var y0 = 0.0; // assume we start at zero 851 nodeValues.SetVariableValue(varName, y0, Vector.Zero); 852 853 if (latentValues != null) { 854 latentValues[latentValueRowIdx, latentValueColIdx++] = y0; 855 } 856 } 857 latentValueColIdx = 0; latentValueRowIdx++; 797 858 798 859 { // CODE BELOW DOESN'T WORK ANYMORE … … 822 883 prevT = t; 823 884 824 for (int i = 0; i < calculatedVariables.Length; i++) { 825 var targetVar = calculatedVariables[i]; 885 // update output for target variables (TODO: if we want to visualize the latent variables then we need to provide a separate output) 886 for (int i = 0; i < targetVariables.Length; i++) { 887 var targetVar = targetVariables[i]; 826 888 var yt = nodeValues.GetVariableValue(targetVar); 827 889 … … 829 891 if (double.IsNaN(yt.Item1) || double.IsInfinity(yt.Item1)) { 830 892 for (; outputRowIdx < fi.Length; outputRowIdx++) { 831 var prevIdx = outputRowIdx - calculatedVariables.Length;893 var prevIdx = outputRowIdx - targetVariables.Length; 832 894 fi[outputRowIdx] = fi[prevIdx]; // current <- prev 833 895 if (jac != null) for (int j = 0; j < jac.GetLength(1); j++) jac[outputRowIdx, j] = jac[prevIdx, j]; … … 840 902 g.CopyTo(jac, outputRowIdx); 841 903 outputRowIdx++; 904 } 905 if (latentValues != null) { 906 foreach (var latentVariable in latentVariables) { 907 var lt = nodeValues.GetVariableValue(latentVariable).Item1; 908 latentValues[latentValueRowIdx, latentValueColIdx++] = lt; 909 } 910 latentValueRowIdx++; latentValueColIdx = 0; 842 911 } 843 912 … … 1451 1520 1452 1521 #region helper 1522 1523 private static IEnumerable<T> EveryNth<T>(IEnumerable<T> xs, int step) { 1524 var e = xs.GetEnumerator(); 1525 while (e.MoveNext()) { 1526 for (int i = 0; i < step; i++) { 1527 if (!e.MoveNext()) yield break; 1528 } 1529 yield return e.Current; 1530 } 1531 } 1453 1532 1454 1533 private void InitAllParameters() { -
branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/Solution.cs
r16653 r16660 86 86 } 87 87 88 public IEnumerable<double[]> Predict(IntRange episode, int forecastHorizon , out double snmse) {88 public IEnumerable<double[]> Predict(IntRange episode, int forecastHorizon) { 89 89 var forecastEpisode = new IntRange(episode.Start, episode.End + forecastHorizon); 90 90 // … … 92 92 // snmse = Problem.OptimizeForEpisodes(trees, problemData, targetVars, latentVariables, random, new[] { forecastEpisode }, 100, numericIntegrationSteps, odeSolver); 93 93 94 var inputVariables = trees.SelectMany(t => t.IterateNodesPrefix().OfType<VariableTreeNode>().Select(n => n.VariableName)).Except(targetVars); 94 var inputVariables = trees.SelectMany(t => t.IterateNodesPrefix().OfType<VariableTreeNode>().Select(n => n.VariableName)) 95 .Except(targetVars) 96 .Except(latentVariables) 97 .Distinct(); 95 98 96 99 var optimizationData = new Problem.OptimizationData(trees, targetVars, inputVariables.ToArray(), problemData, null, new[] { forecastEpisode }, numericIntegrationSteps, latentVariables, odeSolver); … … 99 102 // var theta = Problem.ExtractParametersFromTrees(trees); 100 103 101 snmse = 0.0; // TODO 102 return Problem.Integrate(optimizationData).Select(p => p.Select(pi => pi.Item1).ToArray()).ToArray(); 104 105 var fi = new double[forecastEpisode.Size * targetVars.Length]; 106 var jac = new double[forecastEpisode.Size * targetVars.Length, optimizationData.nodeValueLookup.ParameterCount]; 107 var latentValues = new double[forecastEpisode.Size, LatentVariables.Length]; 108 Problem.Integrate(optimizationData, fi, jac, latentValues); 109 for (int i = 0; i < forecastEpisode.Size; i++) { 110 var res = new double[targetVars.Length + latentVariables.Length]; 111 for (int j = 0; j < targetVars.Length; j++) { 112 res[j] = fi[i * targetVars.Length + j]; 113 } 114 for (int j = 0; j < latentVariables.Length; j++) { 115 res[targetVars.Length + j] = latentValues[i, j]; 116 } 117 yield return res; 118 } 103 119 } 104 120 } -
branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/SolutionView.cs
r16400 r16660 73 73 74 74 double snmse; 75 var predictions = Content.Predict(predictionEpisode, forecastHorizon , out snmse).ToArray();76 errorLabel.Text = $"SNMSE: { snmse:e4}";75 var predictions = Content.Predict(predictionEpisode, forecastHorizon).ToArray(); 76 errorLabel.Text = $"SNMSE: {0.0:e4}"; 77 77 var trainingPredictions = predictions.Take(predictionEpisode.Size).ToArray(); 78 78 var forecastPredictions = predictions.Skip(predictionEpisode.Size).ToArray();
Note: See TracChangeset
for help on using the changeset viewer.