Changeset 18197


Ignore:
Timestamp:
01/14/22 12:06:18 (7 days ago)
Author:
mkommend
Message:

#3136: Ommited parameter optimization of variable weights in the template part of the tree.

Location:
branches/3136_Structural_GP
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/3136_Structural_GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/ParameterOptimization.cs

    r18192 r18197  
    2727namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
    2828  public static class ParameterOptimization {
    29     public static double OptimizeTreeParameters(IRegressionProblemData problemData, ISymbolicExpressionTree tree,
    30       int maxIterations = 10, bool updateParametersInTree = true, bool updateVariableWeights = true,
     29    public static double OptimizeTreeParameters(IRegressionProblemData problemData, ISymbolicExpressionTree tree, int maxIterations = 10,
     30      bool updateParametersInTree = true, bool updateVariableWeights = true, IEnumerable<ISymbolicExpressionTreeNode> excludeNodes = null,
    3131      double lowerEstimationLimit = double.MinValue, double upperEstimationLimit = double.MaxValue,
    3232      IEnumerable<int> rows = null, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter = null,
     
    3535      if (rows == null) rows = problemData.TrainingIndices;
    3636      if (interpreter == null) interpreter = new SymbolicDataAnalysisExpressionTreeBatchInterpreter();
     37      if (excludeNodes == null) excludeNodes = Enumerable.Empty<ISymbolicExpressionTreeNode>();
    3738
    3839      // Numeric parameters in the tree become variables for parameter optimization.
     
    4647      TreeToAutoDiffTermConverter.ParametricFunction func;
    4748      TreeToAutoDiffTermConverter.ParametricFunctionGradient func_grad;
    48       if (!TreeToAutoDiffTermConverter.TryConvertToAutoDiff(tree, updateVariableWeights, addLinearScalingTerms: false, out parameters, out initialParameters, out func, out func_grad))
     49      if (!TreeToAutoDiffTermConverter.TryConvertToAutoDiff(tree,
     50        updateVariableWeights, addLinearScalingTerms: false, excludeNodes,
     51        out parameters, out initialParameters, out func, out func_grad))
    4952        throw new NotSupportedException("Could not optimize parameters of symbolic expression tree due to not supported symbols used in the tree.");
    5053      var parameterEntries = parameters.ToArray(); // order of entries must be the same for x
     
    112115      //             request was submitted.
    113116      if (rep.terminationtype > 0) {
    114         UpdateParameters(tree, c, updateVariableWeights);
     117        UpdateParameters(tree, c, updateVariableWeights, excludeNodes);
    115118      }
    116119      var quality = SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator.Calculate(
     
    119122        lowerEstimationLimit, upperEstimationLimit);
    120123
    121       if (!updateParametersInTree) UpdateParameters(tree, initialParameters, updateVariableWeights);
     124      if (!updateParametersInTree) UpdateParameters(tree, initialParameters, updateVariableWeights, excludeNodes);
    122125
    123126      if (originalQuality < quality || double.IsNaN(quality)) {
    124         UpdateParameters(tree, initialParameters, updateVariableWeights);
     127        UpdateParameters(tree, initialParameters, updateVariableWeights, excludeNodes);
    125128        return originalQuality;
    126129      }
     
    128131    }
    129132
    130     private static void UpdateParameters(ISymbolicExpressionTree tree, double[] parameters, bool updateVariableWeights) {
     133    private static void UpdateParameters(ISymbolicExpressionTree tree, double[] parameters,
     134      bool updateVariableWeights, IEnumerable<ISymbolicExpressionTreeNode> excludedNodes) {
    131135      int i = 0;
    132       foreach (var node in tree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>()) {
     136      foreach (var node in tree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>().Except(excludedNodes)) {
    133137        NumberTreeNode numberTreeNode = node as NumberTreeNode;
    134138        VariableTreeNodeBase variableTreeNodeBase = node as VariableTreeNodeBase;
     
    140144        } else if (updateVariableWeights && variableTreeNodeBase != null)
    141145          variableTreeNodeBase.Weight = parameters[i++];
    142         else if (factorVarTreeNode != null) {
     146        else if (updateVariableWeights && factorVarTreeNode != null) {
    143147          for (int j = 0; j < factorVarTreeNode.Weights.Length; j++)
    144148            factorVarTreeNode.Weights[j] = parameters[i++];
  • branches/3136_Structural_GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/StructuredSymbolicRegressionSingleObjectiveProblem.cs

    r18194 r18197  
    2121
    2222using System;
     23using System.Collections.Generic;
    2324using System.Linq;
    2425using HEAL.Attic;
     
    279280        throw new ArgumentException("No structure template defined!");
    280281
    281       var tree = BuildTreeFromIndividual(templateTree, individual, updateNumericParameters: StructureTemplate.ContainsNumericParameters);
     282      var tree = BuildTreeFromIndividual(templateTree, individual, containsNumericParameters: StructureTemplate.ContainsNumericParameters);
    282283      individual[SymbolicExpressionTreeName] = tree;
    283284
    284285      if (OptimizeParameters) {
    285         ParameterOptimization.OptimizeTreeParameters(ProblemData, tree, interpreter: Interpreter);
     286        var excludeNodes = GetTemplateTreeNodes(tree.Root).OfType<IVariableTreeNode>();
     287        ParameterOptimization.OptimizeTreeParameters(ProblemData, tree, interpreter: Interpreter, excludeNodes: excludeNodes);
    286288      } else if (ApplyLinearScaling) {
    287289        LinearScaling.AdjustLinearScalingParams(ProblemData, tree, Interpreter);
    288290      }
    289291
    290       UpdateIndividualFromTree(tree, individual, updateNumericParameters: StructureTemplate.ContainsNumericParameters);
     292      UpdateIndividualFromTree(tree, individual, containsNumericParameters: StructureTemplate.ContainsNumericParameters);
    291293
    292294      //calculate NMSE
     
    317319    }
    318320
    319     private static ISymbolicExpressionTree BuildTreeFromIndividual(ISymbolicExpressionTree template, Individual individual, bool updateNumericParameters) {
     321    private static IEnumerable<ISymbolicExpressionTreeNode> GetTemplateTreeNodes(ISymbolicExpressionTreeNode rootNode) {
     322      yield return rootNode;
     323      foreach (var node in rootNode.Subtrees) {
     324        if (node is SubFunctionTreeNode) {
     325          yield return node;
     326          continue;
     327        }
     328
     329        foreach (var subNode in GetTemplateTreeNodes(node))
     330          yield return subNode;
     331      }
     332    }
     333
     334    private static ISymbolicExpressionTree BuildTreeFromIndividual(ISymbolicExpressionTree template, Individual individual, bool containsNumericParameters) {
    320335      var resolvedTree = (ISymbolicExpressionTree)template.Clone();
    321336
    322337      //set numeric parameter values
    323       if (updateNumericParameters) {
     338      if (containsNumericParameters) {
    324339        var realVector = individual.RealVector(NumericParametersEncoding);
    325340        var numberTreeNodes = resolvedTree.IterateNodesPrefix().OfType<NumberTreeNode>().ToArray();
     
    345360    }
    346361
    347     private static void UpdateIndividualFromTree(ISymbolicExpressionTree tree, Individual individual, bool updateNumericParameters) {
     362    private static void UpdateIndividualFromTree(ISymbolicExpressionTree tree, Individual individual, bool containsNumericParameters) {
    348363      var clonedTree = (ISymbolicExpressionTree)tree.Clone();
    349364
     
    357372        var rootNode = (SymbolicExpressionTreeTopLevelNode)new ProgramRootSymbol().CreateTreeNode();
    358373        rootNode.SetGrammar(grammar);
    359 
    360374        var startNode = (SymbolicExpressionTreeTopLevelNode)new StartSymbol().CreateTreeNode();
    361375        startNode.SetGrammar(grammar);
     
    368382
    369383      //set numeric parameter values
    370       if (updateNumericParameters) {
     384      if (containsNumericParameters) {
    371385        var realVector = individual.RealVector(NumericParametersEncoding);
    372386        var numberTreeNodes = clonedTree.IterateNodesPrefix().OfType<NumberTreeNode>().ToArray();
  • branches/3136_Structural_GP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs

    r18146 r18197  
    106106      out ParametricFunctionGradient func_grad) {
    107107
     108      return TryConvertToAutoDiff(tree, makeVariableWeightsVariable, addLinearScalingTerms, Enumerable.Empty<ISymbolicExpressionTreeNode>(),
     109        out parameters, out initialParamValues, out func, out func_grad);
     110    }
     111
     112    public static bool TryConvertToAutoDiff(ISymbolicExpressionTree tree, bool makeVariableWeightsVariable, bool addLinearScalingTerms, IEnumerable<ISymbolicExpressionTreeNode> excludedNodes,
     113      out List<DataForVariable> parameters, out double[] initialParamValues,
     114      out ParametricFunction func,
     115      out ParametricFunctionGradient func_grad) {
     116
    108117      // use a transformator object which holds the state (variable list, parameter list, ...) for recursive transformation of the tree
    109       var transformator = new TreeToAutoDiffTermConverter(makeVariableWeightsVariable, addLinearScalingTerms);
     118      var transformator = new TreeToAutoDiffTermConverter(makeVariableWeightsVariable, addLinearScalingTerms, excludedNodes);
    110119      AutoDiff.Term term;
    111120      try {
     
    134143    private readonly bool makeVariableWeightsVariable;
    135144    private readonly bool addLinearScalingTerms;
    136 
    137     private TreeToAutoDiffTermConverter(bool makeVariableWeightsVariable, bool addLinearScalingTerms) {
     145    private readonly HashSet<ISymbolicExpressionTreeNode> excludedNodes;
     146
     147    private TreeToAutoDiffTermConverter(bool makeVariableWeightsVariable, bool addLinearScalingTerms, IEnumerable<ISymbolicExpressionTreeNode> excludedNodes) {
    138148      this.makeVariableWeightsVariable = makeVariableWeightsVariable;
    139149      this.addLinearScalingTerms = addLinearScalingTerms;
     150      this.excludedNodes = new HashSet<ISymbolicExpressionTreeNode>(excludedNodes);
     151
    140152      this.initialParamValues = new List<double>();
    141153      this.parameters = new Dictionary<DataForVariable, AutoDiff.Variable>();
     
    161173        var par = FindOrCreateParameter(parameters, varNode.VariableName, varValue);
    162174
    163         if (makeVariableWeightsVariable) {
     175        if (makeVariableWeightsVariable && !excludedNodes.Contains(node)) {
    164176          initialParamValues.Add(varNode.Weight);
    165177          var w = new AutoDiff.Variable();
     
    176188          var par = FindOrCreateParameter(parameters, factorVarNode.VariableName, variableValue);
    177189
    178           initialParamValues.Add(factorVarNode.GetValue(variableValue));
    179           var wVar = new AutoDiff.Variable();
    180           variables.Add(wVar);
    181 
    182           products.Add(AutoDiff.TermBuilder.Product(wVar, par));
     190          if (makeVariableWeightsVariable && !excludedNodes.Contains(node)) {
     191            initialParamValues.Add(factorVarNode.GetValue(variableValue));
     192            var wVar = new AutoDiff.Variable();
     193            variables.Add(wVar);
     194
     195            products.Add(AutoDiff.TermBuilder.Product(wVar, par));
     196          } else {
     197            var weight = factorVarNode.GetValue(variableValue);
     198            products.Add(weight * par);
     199          }
     200
    183201        }
    184202        return AutoDiff.TermBuilder.Sum(products);
     
    188206        var par = FindOrCreateParameter(parameters, varNode.VariableName, string.Empty, varNode.Lag);
    189207
    190         if (makeVariableWeightsVariable) {
     208        if (makeVariableWeightsVariable && !excludedNodes.Contains(node)) {
    191209          initialParamValues.Add(varNode.Weight);
    192210          var w = new AutoDiff.Variable();
Note: See TracChangeset for help on using the changeset viewer.