Changeset 17476
- Timestamp:
- 03/12/20 17:51:39 (5 years ago)
- Location:
- branches/3040_VectorBasedGP
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/TensorFlowConstantOptimizationEvaluator.cs
r17475 r17476 23 23 using System.Collections; 24 24 using System.Collections.Generic; 25 using System.Diagnostics; 25 26 using System.Linq; 26 27 using System.Threading; … … 31 32 using HeuristicLab.Parameters; 32 33 using HEAL.Attic; 34 using NumSharp; 33 35 using Tensorflow; 34 36 using static Tensorflow.Binding; … … 92 94 CancellationToken cancellationToken = default(CancellationToken), EvaluationsCounter counter = null) { 93 95 94 bool success = TreeToTensorConverter.TryConvert(tree, updateVariableWeights, applyLinearScaling, 95 out Tensor prediction, out Dictionary<TreeToTensorConverter.DataForVariable, Tensor> variables/*, out double[] initialConstants*/); 96 var vectorVariables = tree.IterateNodesBreadth() 97 .OfType<VariableTreeNodeBase>() 98 .Where(node => problemData.Dataset.VariableHasType<DoubleVector>(node.VariableName)) 99 .Select(node => node.VariableName); 100 101 int? vectorLength = null; 102 if (vectorVariables.Any()) { 103 vectorLength = vectorVariables.Select(var => problemData.Dataset.GetDoubleVectorValues(var, rows)).First().First().Count; 104 } 105 int numRows = rows.Count(); 106 107 bool success = TreeToTensorConverter.TryConvert(tree, 108 numRows, vectorLength, 109 updateVariableWeights, applyLinearScaling, 110 out Tensor prediction, 111 out Dictionary<Tensor, string> parameters, out List<Tensor> variables/*, out double[] initialConstants*/); 96 112 97 113 var target = tf.placeholder(tf.float64, name: problemData.TargetVariable); … … 99 115 // mse 100 116 var costs = tf.reduce_sum(tf.square(prediction - target)) / (2.0 * samples); 101 var optimizer = tf.train.GradientDescentOptimizer((float)learningRate) ;117 var optimizer = tf.train.GradientDescentOptimizer((float)learningRate).minimize(costs); 102 118 103 119 // features as feed items 104 120 var variablesFeed = new Hashtable(); 105 foreach (var kvp in variables) { 106 var variableName = kvp.Key.variableName; 107 var variable = kvp.Value; 108 if (problemData.Dataset.VariableHasType<double>(variableName)) 109 variablesFeed.Add(variable, problemData.Dataset.GetDoubleValues(variableName, rows)); 110 if (problemData.Dataset.VariableHasType<string>(variableName)) 111 variablesFeed.Add(variable, problemData.Dataset.GetStringValues(variableName, rows)); 112 if (problemData.Dataset.VariableHasType<DoubleVector>(variableName)) 113 variablesFeed.Add(variable, problemData.Dataset.GetDoubleVectorValues(variableName, rows)); 114 throw new NotSupportedException($"Type of the variable is not supported: {variableName}"); 121 foreach (var kvp in parameters) { 122 var variable = kvp.Key; 123 var variableName = kvp.Value; 124 if (problemData.Dataset.VariableHasType<double>(variableName)) { 125 var data = problemData.Dataset.GetDoubleValues(variableName, rows).ToArray(); 126 if (vectorLength.HasValue) { 127 var vectorData = new double[numRows][]; 128 for (int i = 0; i < numRows; i++) 129 vectorData[i] = Enumerable.Repeat(data[i], vectorLength.Value).ToArray(); 130 variablesFeed.Add(variable, np.array(vectorData)); 131 } else 132 variablesFeed.Add(variable, np.array(data, copy: false)); 133 //} else if (problemData.Dataset.VariableHasType<string>(variableName)) { 134 // variablesFeed.Add(variable, problemData.Dataset.GetStringValues(variableName, rows)); 135 } else if (problemData.Dataset.VariableHasType<DoubleVector>(variableName)) { 136 var data = problemData.Dataset.GetDoubleVectorValues(variableName, rows).Select(x => x.ToArray()).ToArray(); 137 variablesFeed.Add(variable, np.array(data)); 138 } else 139 throw new NotSupportedException($"Type of the variable is not supported: {variableName}"); 115 140 } 116 variablesFeed.Add(target, problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows)); 141 var targetData = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows).ToArray(); 142 variablesFeed.Add(target, np.array(targetData, copy: false)); 117 143 118 144 119 145 using (var session = tf.Session()) { 146 session.run(tf.global_variables_initializer()); 147 148 Trace.WriteLine("Weights:"); 149 foreach (var v in variables) 150 Trace.WriteLine($"{v.name}: {session.run(v).ToString(true)}"); 151 120 152 for (int i = 0; i < maxIterations; i++) { 121 optimizer.minimize(costs); 122 var result = session.run(optimizer, variablesFeed); 153 154 //optimizer.minimize(costs); 155 session.run(optimizer, variablesFeed); 156 157 Trace.WriteLine("Weights:"); 158 foreach (var v in variables) 159 Trace.WriteLine($"{v.name}: {session.run(v).ToString(true)}"); 123 160 } 124 161 } 125 optimizer.minimize(costs);126 162 127 163 if (!success) -
branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToTensorConverter.cs
r17474 r17476 23 23 using System.Collections.Generic; 24 24 using System.Linq; 25 using System.Runtime.Serialization;26 using AutoDiff;27 25 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 28 26 using Tensorflow; 29 27 using static Tensorflow.Binding; 28 using DoubleVector = MathNet.Numerics.LinearAlgebra.Vector<double>; 30 29 31 30 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { … … 55 54 #endregion 56 55 57 public static bool TryConvert(ISymbolicExpressionTree tree, bool makeVariableWeightsVariable, bool addLinearScalingTerms, 58 out Tensor graph, out Dictionary<DataForVariable, Tensor> variables/*, out double[] initialConstants*/) { 56 public static bool TryConvert(ISymbolicExpressionTree tree, int numRows, int? vectorLength, 57 bool makeVariableWeightsVariable, bool addLinearScalingTerms, 58 out Tensor graph, out Dictionary<Tensor, string> parameters, out List<Tensor> variables 59 /*, out double[] initialConstants*/) { 59 60 60 61 try { 61 var converter = new TreeToTensorConverter( makeVariableWeightsVariable, addLinearScalingTerms);62 var converter = new TreeToTensorConverter(numRows, vectorLength, makeVariableWeightsVariable, addLinearScalingTerms); 62 63 graph = converter.ConvertNode(tree.Root.GetSubtree(0)); 63 64 64 65 //var parametersEntries = converter.parameters.ToList(); // guarantee same order for keys and values 65 variables = converter.parameters; // parametersEntries.Select(kvp => kvp.Value).ToList(); 66 parameters = converter.parameters; // parametersEntries.Select(kvp => kvp.Value).ToList(); 67 variables = converter.variables; 66 68 //initialConstants = converter.initialConstants.ToArray(); 67 69 return true; 68 70 } catch (NotSupportedException) { 69 71 graph = null; 72 parameters = null; 70 73 variables = null; 71 74 //initialConstants = null; … … 74 77 } 75 78 79 private readonly int numRows; 80 private readonly int? vectorLength; 76 81 private readonly bool makeVariableWeightsVariable; 77 82 private readonly bool addLinearScalingTerms; 78 83 79 84 //private readonly List<double> initialConstants = new List<double>(); 80 private readonly Dictionary< DataForVariable, Tensor> parameters = new Dictionary<DataForVariable, Tensor>();85 private readonly Dictionary<Tensor, string> parameters = new Dictionary<Tensor, string>(); 81 86 private readonly List<Tensor> variables = new List<Tensor>(); 82 87 83 private TreeToTensorConverter(bool makeVariableWeightsVariable, bool addLinearScalingTerms) { 88 private TreeToTensorConverter(int numRows, int? vectorLength, bool makeVariableWeightsVariable, bool addLinearScalingTerms) { 89 this.numRows = numRows; 90 this.vectorLength = vectorLength; 84 91 this.makeVariableWeightsVariable = makeVariableWeightsVariable; 85 92 this.addLinearScalingTerms = addLinearScalingTerms; … … 91 98 var value = ((ConstantTreeNode)node).Value; 92 99 //initialConstants.Add(value); 93 var var = tf.Variable(value );100 var var = tf.Variable(value, name: $"c_{variables.Count}", dtype: tf.float64); 94 101 variables.Add(var); 95 102 return var; 96 103 } 97 104 98 if (node.Symbol is Variable || node.Symbol is BinaryFactorVariable) {105 if (node.Symbol is Variable/* || node.Symbol is BinaryFactorVariable*/) { 99 106 var varNode = node as VariableTreeNodeBase; 100 var factorVarNode = node as BinaryFactorVariableTreeNode;107 //var factorVarNode = node as BinaryFactorVariableTreeNode; 101 108 // factor variable values are only 0 or 1 and set in x accordingly 102 var varValue = factorVarNode != null ? factorVarNode.VariableValue : string.Empty; 103 var par = FindOrCreateParameter(parameters, varNode.VariableName, varValue); 109 //var varValue = factorVarNode != null ? factorVarNode.VariableValue : string.Empty; 110 //var par = FindOrCreateParameter(parameters, varNode.VariableName, varValue); 111 var shape = vectorLength.HasValue 112 ? new TensorShape(numRows, vectorLength.Value) 113 : new TensorShape(numRows); 114 var par = tf.placeholder(tf.float64, shape: shape, name: varNode.VariableName); 115 parameters.Add(par, varNode.VariableName); 104 116 105 117 if (makeVariableWeightsVariable) { 106 118 //initialConstants.Add(varNode.Weight); 107 var w = tf.Variable(varNode.Weight );119 var w = tf.Variable(varNode.Weight, name: $"w_{varNode.VariableName}_{variables.Count}", dtype: tf.float64); 108 120 variables.Add(w); 109 121 return w * par; … … 117 129 var products = new List<Tensor>(); 118 130 foreach (var variableValue in factorVarNode.Symbol.GetVariableValues(factorVarNode.VariableName)) { 119 var par = FindOrCreateParameter(parameters, factorVarNode.VariableName, variableValue); 131 //var par = FindOrCreateParameter(parameters, factorVarNode.VariableName, variableValue); 132 var par = tf.placeholder(tf.float64, shape: new TensorShape(numRows), name: factorVarNode.VariableName); 133 parameters.Add(par, factorVarNode.VariableName); 120 134 121 135 var value = factorVarNode.GetValue(variableValue); 122 136 //initialConstants.Add(value); 123 var wVar = tf.Variable(value );137 var wVar = tf.Variable(value, name: $"f_{factorVarNode.VariableName}_{variables.Count}"); 124 138 variables.Add(wVar); 125 139 … … 127 141 } 128 142 129 return tf.add_n(products.ToArray());143 return products.Aggregate((a, b) => a + b); 130 144 } 131 145 … … 136 150 } 137 151 138 return t f.add_n(terms.ToArray());152 return terms.Aggregate((a, b) => a + b); 139 153 } 140 154 … … 148 162 149 163 if (terms.Count == 1) return -terms[0]; 150 else return t f.add_n(terms.ToArray());164 else return terms.Aggregate((a, b) => a + b); 151 165 } 152 166 … … 233 247 if (node.Symbol is Mean) { 234 248 return tf.reduce_mean( 235 ConvertNode(node.GetSubtree(0))); 249 ConvertNode(node.GetSubtree(0)), 250 axis: new[] { 1 }); 236 251 } 237 252 238 253 //if (node.Symbol is StandardDeviation) { 239 254 // return tf.reduce_std( 240 // ConvertNode(node.GetSubtree(0))); 255 // ConvertNode(node.GetSubtree(0)), 256 // axis: new [] { 1 } 257 // ); 241 258 //} 242 259 243 260 if (node.Symbol is Sum) { 244 261 return tf.reduce_sum( 245 ConvertNode(node.GetSubtree(0))); 262 ConvertNode(node.GetSubtree(0)), 263 axis: new[] { 1 }); 246 264 } 247 265 … … 249 267 if (addLinearScalingTerms) { 250 268 // scaling variables α, β are given at the beginning of the parameter vector 251 var alpha = tf.Variable(1.0); 252 var beta = tf.Variable(0.0); 269 var alpha = tf.Variable(1.0, name: $"alpha_{1.0}", dtype: tf.float64); 270 var beta = tf.Variable(0.0, name: $"beta_{0.0}", dtype: tf.float64); 271 variables.Add(alpha); 253 272 variables.Add(beta); 254 variables.Add(alpha);255 273 var t = ConvertNode(node.GetSubtree(0)); 256 274 return t * alpha + beta; … … 268 286 if (!parameters.TryGetValue(data, out var par)) { 269 287 // not found -> create new parameter and entries in names and values lists 270 par = tf.placeholder(tf.float64, name: varName);288 par = tf.placeholder(tf.float64, shape: new TensorShape(-1), name: varName); 271 289 parameters.Add(data, par); 272 290 } … … 279 297 where 280 298 !(n.Symbol is Variable) && 281 !(n.Symbol is BinaryFactorVariable) &&282 !(n.Symbol is FactorVariable) &&299 //!(n.Symbol is BinaryFactorVariable) && 300 //!(n.Symbol is FactorVariable) && 283 301 !(n.Symbol is Constant) && 284 302 !(n.Symbol is Addition) &&
Note: See TracChangeset
for help on using the changeset viewer.