- Timestamp:
- 03/22/22 13:28:56 (2 years ago)
- Location:
- branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToDiffSharpConverter.cs
r17930 r18239 19 19 */ 20 20 #endregion 21 22 #if INCLUDE_DIFFSHARP 21 23 22 24 using System; … … 505 507 } 506 508 } 509 510 #endif -
branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToTensorConverter.cs
r18238 r18239 20 20 #endregion 21 21 22 #define EXPLICIT_SHAPE23 24 22 using System; 25 23 using System.Collections.Generic; 26 24 using System.Linq; 27 25 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 28 using NumSharp;29 26 using Tensorflow; 27 using Tensorflow.NumPy; 30 28 using static Tensorflow.Binding; 29 using DoubleVector = MathNet.Numerics.LinearAlgebra.Vector<double>; 31 30 32 31 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 33 32 public class TreeToTensorConverter { 34 33 34 //private static readonly TF_DataType DataType = tf.float64; 35 35 private static readonly TF_DataType DataType = tf.float32; 36 36 37 public static bool TryConvert(ISymbolicExpressionTree tree, int numRows, Dictionary<string, int> variableLengths, 38 bool makeVariableWeightsVariable, bool addLinearScalingTerms, 39 out Tensor graph, out Dictionary<Tensor, string> parameters, out List<Tensor> variables) { 37 public static bool TryPrepareTree( 38 ISymbolicExpressionTree tree, 39 IRegressionProblemData problemData, List<int> rows, 40 bool updateVariableWeights, bool applyLinearScaling, 41 bool eagerEvaluation, 42 out Dictionary<string, Tensor> inputFeatures, out Tensor target, 43 out Dictionary<ISymbolicExpressionTreeNode, ResourceVariable[]> variables) { 40 44 41 45 try { 42 var converter = new TreeToTensorConverter(numRows, variableLengths, makeVariableWeightsVariable, addLinearScalingTerms); 43 graph = converter.ConvertNode(tree.Root.GetSubtree(0)); 44 45 parameters = converter.parameters; 46 var converter = new TreeToTensorConverter( 47 problemData, rows, 48 updateVariableWeights, applyLinearScaling, 49 eagerEvaluation 50 ); 51 52 if (eagerEvaluation) 53 tf.enable_eager_execution(); 54 else 55 tf.compat.v1.disable_eager_execution(); 56 57 converter.PrepareNode(tree.Root.GetSubtree(0)); 58 59 inputFeatures = converter.inputFeatures; 60 target = InputFeatureToTensor(problemData.TargetVariable, problemData, rows); 46 61 variables = converter.variables; 62 47 63 return true; 48 64 } catch (NotSupportedException) { 49 graph= null;50 parameters= null;65 inputFeatures = null; 66 target= null; 51 67 variables = null; 52 68 return false; 53 69 } 54 } 55 56 private readonly int numRows; 57 private readonly Dictionary<string, int> variableLengths; 70 71 } 72 73 public static bool TryEvaluate( 74 ISymbolicExpressionTree tree, 75 Dictionary<string, Tensor> inputFeatures, Dictionary<ISymbolicExpressionTreeNode, ResourceVariable[]> variables, 76 bool makeVariableWeightsVariable, bool addLinearScalingTerms, 77 bool eagerEvaluation, 78 out Tensor prediction) { 79 80 try { 81 var converter = new TreeToTensorConverter( 82 inputFeatures, variables, 83 makeVariableWeightsVariable, addLinearScalingTerms, 84 eagerEvaluation 85 ); 86 87 if (eagerEvaluation) 88 tf.enable_eager_execution(); 89 else 90 tf.compat.v1.disable_eager_execution(); 91 92 prediction = converter.EvaluateNode(tree.Root.GetSubtree(0)); 93 94 return true; 95 } catch (NotSupportedException) { 96 prediction = null; 97 return false; 98 } 99 100 } 101 102 //public static bool TryConvert/*Lazy/Graph*/( 103 // ISymbolicExpressionTree tree, 104 // Dictionary<string, Tensor> inputFeatures, Dictionary<ISymbolicExpressionTreeNode, ResourceVariable[]> variables, 105 // bool makeVariableWeightsVariable, bool addLinearScalingTerms, 106 // out Tensor prediction) { 107 108 // try { 109 // var converter = new TreeToTensorConverter( 110 // inputFeatures, variables, 111 // makeVariableWeightsVariable, addLinearScalingTerms, 112 // eagerEvaluation: false 113 // ); 114 115 // tf.compat.v1.disable_eager_execution(); 116 // prediction = converter.EvaluateNode(tree.Root.GetSubtree(0)); 117 // return true; 118 // } catch (NotSupportedException) { 119 // prediction = null; 120 // return false; 121 // } 122 //} 123 124 125 private readonly IDataAnalysisProblemData problemData; 126 private readonly List<int> rows; 127 128 private readonly Dictionary<string, Tensor> inputFeatures = new Dictionary<string, Tensor>(); 129 private readonly Dictionary<ISymbolicExpressionTreeNode, ResourceVariable[]> variables = new Dictionary<ISymbolicExpressionTreeNode, ResourceVariable[]>(); 130 58 131 private readonly bool makeVariableWeightsVariable; 59 132 private readonly bool addLinearScalingTerms; 60 61 private readonly Dictionary<Tensor, string> parameters = new Dictionary<Tensor, string>(); 62 private readonly List<Tensor> variables = new List<Tensor>(); 63 64 private TreeToTensorConverter(int numRows, Dictionary<string, int> variableLengths, bool makeVariableWeightsVariable, bool addLinearScalingTerms) { 65 this.numRows = numRows; 66 this.variableLengths = variableLengths; 133 private readonly bool eagerEvaluation; 134 135 private TreeToTensorConverter( 136 IDataAnalysisProblemData problemData, List<int> rows, 137 bool makeVariableWeightsVariable, bool addLinearScalingTerms, 138 bool eagerEvaluation 139 ) { 140 this.problemData = problemData; 141 this.rows = rows; 142 67 143 this.makeVariableWeightsVariable = makeVariableWeightsVariable; 68 144 this.addLinearScalingTerms = addLinearScalingTerms; 69 } 70 71 72 private Tensor ConvertNode(ISymbolicExpressionTreeNode node) { 145 this.eagerEvaluation = eagerEvaluation; 146 } 147 148 private TreeToTensorConverter( 149 Dictionary<string, Tensor> inputFeatures, Dictionary<ISymbolicExpressionTreeNode, ResourceVariable[]> variables, 150 bool makeVariableWeightsVariable, bool addLinearScalingTerms, 151 bool eagerEvaluation 152 ) { 153 this.inputFeatures = inputFeatures; 154 this.variables = variables; 155 156 this.makeVariableWeightsVariable = makeVariableWeightsVariable; 157 this.addLinearScalingTerms = addLinearScalingTerms; 158 this.eagerEvaluation = eagerEvaluation; 159 } 160 161 private static Tensor InputFeatureToTensor(string var, IDataAnalysisProblemData problemData, List<int> rows) { 162 if (problemData.Dataset.VariableHasType<double>(var)) { 163 var data = problemData.Dataset.GetDoubleValues(var, rows).Select(x => (float)x).ToArray(); 164 return tf.convert_to_tensor(np.array(data).reshape(new Shape(rows.Count, 1)), DataType); 165 } else if (problemData.Dataset.VariableHasType<DoubleVector>(var)) { 166 var data = problemData.Dataset.GetDoubleVectorValues(var, rows).SelectMany(x => x.Select(y => (float)y)).ToArray(); 167 return tf.convert_to_tensor(np.array(data).reshape(new Shape(rows.Count, -1)), DataType); 168 } else throw new NotSupportedException($"Type of the variable is not supported: {var}"); 169 } 170 private static Tensor InputFeatureToPlaceholder(string var, IDataAnalysisProblemData problemData, List<int> rows) { 171 if (problemData.Dataset.VariableHasType<double>(var)) { 172 return tf.placeholder(DataType, new Shape(rows.Count, 1), name: var); 173 } else if (problemData.Dataset.VariableHasType<DoubleVector>(var)) { 174 //var vectorLength = problemData.Dataset.GetDoubleVectorValues(var, rows).Select(v => v.Count).Distinct().Single(); 175 var vectorLength = problemData.Dataset.GetDoubleVectorValue(var, rows[0]).Count; 176 return tf.placeholder(DataType, new Shape(rows.Count, vectorLength), name: var); 177 } else throw new NotSupportedException($"Type of the variable is not supported: {var}"); 178 } 179 180 private void PrepareNode(ISymbolicExpressionTreeNode node) { 181 if (node.Symbol is Constant ) { 182 var constantNode = (ConstantTreeNode)node; 183 var value = (float)constantNode.Value; 184 var value_arr = np.array(value).reshape(new Shape(1, 1)); 185 var c = tf.Variable(value_arr, name: $"c_{variables.Count}", dtype: DataType); 186 variables.Add(node, new[] { c }); 187 } else if (node.Symbol is Variable) { 188 var varNode = (VariableTreeNodeBase)node; 189 if (makeVariableWeightsVariable) { 190 var w_arr = np.array((float)varNode.Weight).reshape(new Shape(1, 1)); 191 var w = tf.Variable(w_arr, name: $"w_{varNode.VariableName}", dtype: DataType); 192 variables.Add(node, new[] { w }); 193 } 194 if (!inputFeatures.ContainsKey(varNode.VariableName)) { 195 inputFeatures.Add( 196 varNode.VariableName, 197 eagerEvaluation 198 ? InputFeatureToTensor(varNode.VariableName, problemData, rows) 199 : InputFeatureToPlaceholder(varNode.VariableName, problemData, rows)); 200 } 201 } else if (node.Symbol is StartSymbol) { 202 if (addLinearScalingTerms) { 203 var alpha_arr = np.array(1.0f).reshape(new Shape(1, 1)); 204 var alpha = tf.Variable(alpha_arr, name: "alpha", dtype: DataType); 205 var beta_arr = np.array(0.0f).reshape(new Shape(1, 1)); 206 var beta = tf.Variable(beta_arr, name: "beta", dtype: DataType); 207 variables.Add(node, new[] { beta, alpha }); 208 } 209 } 210 211 foreach (var subTree in node.Subtrees) { 212 PrepareNode(subTree); 213 } 214 } 215 216 217 private Tensor EvaluateNode(ISymbolicExpressionTreeNode node) { 73 218 if (node.Symbol is Constant) { 74 var value = (float)((ConstantTreeNode)node).Value; 75 var value_arr = np.array(value).reshape(1, 1); 76 var var = tf.Variable(value_arr, name: $"c_{variables.Count}", dtype: DataType); 77 variables.Add(var); 78 return var; 219 return variables[node][0]; 79 220 } 80 221 81 222 if (node.Symbol is Variable/* || node.Symbol is BinaryFactorVariable*/) { 82 223 var varNode = node as VariableTreeNodeBase; 83 //var factorVarNode = node as BinaryFactorVariableTreeNode; 84 // factor variable values are only 0 or 1 and set in x accordingly 85 //var varValue = factorVarNode != null ? factorVarNode.VariableValue : string.Empty; 86 //var par = FindOrCreateParameter(parameters, varNode.VariableName, varValue); 87 var par = tf.placeholder(DataType, new TensorShape(numRows, variableLengths[varNode.VariableName]), name: varNode.VariableName); 88 parameters.Add(par, varNode.VariableName); 89 224 225 var par = inputFeatures[varNode.VariableName]; // eager or placeholder 90 226 if (makeVariableWeightsVariable) { 91 var w_arr = np.array((float)varNode.Weight).reshape(1, 1); 92 var w = tf.Variable(w_arr, name: $"w_{varNode.VariableName}", dtype: DataType); 93 variables.Add(w); 227 var w = variables[node][0]; 94 228 return w * par; 95 229 } else { … … 119 253 120 254 if (node.Symbol is Addition) { 121 var terms = node.Subtrees.Select( ConvertNode).ToList();255 var terms = node.Subtrees.Select(EvaluateNode).ToList(); 122 256 if (terms.Count == 1) return terms[0]; 123 257 return terms.Aggregate((a, b) => a + b); … … 125 259 126 260 if (node.Symbol is Subtraction) { 127 var terms = node.Subtrees.Select( ConvertNode).ToList();261 var terms = node.Subtrees.Select(EvaluateNode).ToList(); 128 262 if (terms.Count == 1) return -terms[0]; 129 263 return terms.Aggregate((a, b) => a - b); … … 131 265 132 266 if (node.Symbol is Multiplication) { 133 var terms = node.Subtrees.Select( ConvertNode).ToList();267 var terms = node.Subtrees.Select(EvaluateNode).ToList(); 134 268 if (terms.Count == 1) return terms[0]; 135 269 return terms.Aggregate((a, b) => a * b); … … 137 271 138 272 if (node.Symbol is Division) { 139 var terms = node.Subtrees.Select(ConvertNode).ToList(); 140 if (terms.Count == 1) return 1.0f / terms[0]; 273 var terms = node.Subtrees.Select(EvaluateNode).ToList(); 274 //if (terms.Count == 1) return 1.0f / terms[0]; 275 if (terms.Count == 1) return 1.0 / terms[0]; 141 276 return terms.Aggregate((a, b) => a / b); 142 277 } 143 278 144 279 if (node.Symbol is Absolute) { 145 var x1 = ConvertNode(node.GetSubtree(0));280 var x1 = EvaluateNode(node.GetSubtree(0)); 146 281 return tf.abs(x1); 147 282 } 148 283 149 284 if (node.Symbol is AnalyticQuotient) { 150 var x1 = ConvertNode(node.GetSubtree(0));151 var x2 = ConvertNode(node.GetSubtree(1));285 var x1 = EvaluateNode(node.GetSubtree(0)); 286 var x2 = EvaluateNode(node.GetSubtree(1)); 152 287 return x1 / tf.pow(1.0f + x2 * x2, 0.5f); 288 //return x1 / tf.pow(1.0 + x2 * x2, 0.5); 153 289 } 154 290 155 291 if (node.Symbol is Logarithm) { 156 292 return tf.log( 157 ConvertNode(node.GetSubtree(0)));293 EvaluateNode(node.GetSubtree(0))); 158 294 } 159 295 … … 161 297 return tf.pow( 162 298 (float)Math.E, 163 ConvertNode(node.GetSubtree(0))); 299 //Math.E, 300 EvaluateNode(node.GetSubtree(0))); 164 301 } 165 302 166 303 if (node.Symbol is Square) { 167 304 return tf.square( 168 ConvertNode(node.GetSubtree(0)));305 EvaluateNode(node.GetSubtree(0))); 169 306 } 170 307 171 308 if (node.Symbol is SquareRoot) { 172 309 return tf.sqrt( 173 ConvertNode(node.GetSubtree(0)));310 EvaluateNode(node.GetSubtree(0))); 174 311 } 175 312 176 313 if (node.Symbol is Cube) { 177 314 return tf.pow( 178 ConvertNode(node.GetSubtree(0)), 3.0f); 315 EvaluateNode(node.GetSubtree(0)), 3.0f); 316 //ConvertNode(node.GetSubtree(0)), 3.0); 179 317 } 180 318 181 319 if (node.Symbol is CubeRoot) { 182 320 return tf.pow( 183 ConvertNode(node.GetSubtree(0)), 1.0f / 3.0f); 321 EvaluateNode(node.GetSubtree(0)), 1.0f / 3.0f); 322 //ConvertNode(node.GetSubtree(0)), 1.0 / 3.0); 184 323 // TODO 185 324 // f: x < 0 ? -Math.Pow(-x, 1.0 / 3) : Math.Pow(x, 1.0 / 3), … … 189 328 if (node.Symbol is Sine) { 190 329 return tf.sin( 191 ConvertNode(node.GetSubtree(0)));330 EvaluateNode(node.GetSubtree(0))); 192 331 } 193 332 194 333 if (node.Symbol is Cosine) { 195 334 return tf.cos( 196 ConvertNode(node.GetSubtree(0)));335 EvaluateNode(node.GetSubtree(0))); 197 336 } 198 337 199 338 if (node.Symbol is Tangent) { 200 339 return tf.tan( 201 ConvertNode(node.GetSubtree(0)));340 EvaluateNode(node.GetSubtree(0))); 202 341 } 203 342 204 343 if (node.Symbol is Mean) { 205 344 return tf.reduce_mean( 206 ConvertNode(node.GetSubtree(0)),345 EvaluateNode(node.GetSubtree(0)), 207 346 axis: new[] { 1 }, 208 347 keepdims: true); … … 210 349 211 350 if (node.Symbol is StandardDeviation) { 212 return reduce_std(213 ConvertNode(node.GetSubtree(0)),351 return tf.reduce_std( 352 EvaluateNode(node.GetSubtree(0)), 214 353 axis: new[] { 1 }, 215 354 keepdims: true 216 );355 ); 217 356 } 218 357 219 358 if (node.Symbol is Variance) { 220 return reduce_var(221 ConvertNode(node.GetSubtree(0)),359 return tf.reduce_variance( 360 EvaluateNode(node.GetSubtree(0)), 222 361 axis: new[] { 1 } , 223 362 keepdims: true … … 227 366 if (node.Symbol is Sum) { 228 367 return tf.reduce_sum( 229 ConvertNode(node.GetSubtree(0)),368 EvaluateNode(node.GetSubtree(0)), 230 369 axis: new[] { 1 }, 231 370 keepdims: true); … … 233 372 234 373 if (node.Symbol is SubVector) { 235 var tensor = ConvertNode(node.GetSubtree(0));236 int rows = tensor.shape[0], vectorLength =tensor.shape[1];374 var tensor = EvaluateNode(node.GetSubtree(0)); 375 int rows = (int)tensor.shape[0], vectorLength = (int)tensor.shape[1]; 237 376 var windowedNode = (IWindowedSymbolTreeNode)node; 238 377 int startIdx = SymbolicDataAnalysisExpressionTreeVectorInterpreter.ToVectorIdx(windowedNode.Offset, vectorLength); … … 244 383 segments.Add(tensor[new Slice(), new Slice(start, start + count)]); 245 384 } 246 return tf.concat(segments .ToArray(), axis: 1);385 return tf.concat(segments, axis: 1); 247 386 } 248 387 249 388 250 389 if (node.Symbol is StartSymbol) { 251 Tensor prediction; 390 Tensor prediction = EvaluateNode(node.GetSubtree(0)); 391 392 if (prediction.rank != 2 && prediction.shape[1] != 1) 393 throw new InvalidOperationException("Prediction must be a rank 1 (single value per row)."); 394 395 prediction = tf.reshape(prediction, new Shape(-1)); 396 252 397 if (addLinearScalingTerms) { 253 // scaling variables α, β are given at the beginning of the parameter vector 254 var alpha_arr = np.array(1.0f).reshape(1, 1); 255 var alpha = tf.Variable(alpha_arr, name: "alpha", dtype: DataType); 256 var beta_arr = np.array(0.0f).reshape(1, 1); 257 var beta = tf.Variable(beta_arr, name: "beta", dtype: DataType); 258 variables.Add(beta); 259 variables.Add(alpha); 260 var t = ConvertNode(node.GetSubtree(0)); 261 prediction = t * alpha + beta; 398 var vars = variables[node]; 399 Tensor alpha = vars[1], beta = vars[0]; 400 return prediction * alpha + beta; 262 401 } else { 263 prediction = ConvertNode(node.GetSubtree(0)); 264 } 265 266 return tf.reshape(prediction, shape: new[] { -1 }); 402 return prediction; 403 } 267 404 } 268 405 269 406 throw new NotSupportedException($"Node symbol {node.Symbol} is not supported."); 270 }271 272 private static Tensor reduce_var(Tensor input_tensor, int[] axis = null, bool keepdims = false) {273 var means = tf.reduce_mean(input_tensor, axis, true);274 var squared_deviation = tf.square(input_tensor - means);275 return tf.reduce_mean(squared_deviation, axis, keepdims);276 }277 private static Tensor reduce_std(Tensor input_tensor, int[] axis = null, bool keepdims = false) {278 return tf.sqrt(reduce_var(input_tensor, axis, keepdims));279 407 } 280 408 -
branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
r18229 r18239 113 113 <Private>False</Private> 114 114 </Reference> 115 <Reference Include="DiffSharp.Merged, Version=0.8.4.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=AMD64">116 <SpecificVersion>False</SpecificVersion>117 <HintPath>..\..\bin\DiffSharp.Merged.dll</HintPath>118 </Reference>119 115 <Reference Include="HEAL.Attic, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL"> 120 116 <SpecificVersion>False</SpecificVersion> … … 144 140 <Reference Include="System.Data" /> 145 141 <Reference Include="System.Xml" /> 146 <Reference Include="Tensor Flow.NET.Merged, Version=0.15.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">142 <Reference Include="Tensorflow.Binding, Version=0.70.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=AMD64"> 147 143 <SpecificVersion>False</SpecificVersion> 148 <HintPath>..\..\bin\Tensor Flow.NET.Merged.dll</HintPath>144 <HintPath>..\..\bin\Tensorflow.Binding.dll</HintPath> 149 145 </Reference> 150 146 </ItemGroup> -
branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Plugin.cs.frame
r18229 r18239 56 56 [PluginDependency("HeuristicLab.MathNet.Numerics", "4.9.0")] 57 57 [PluginDependency("HeuristicLab.TensorFlowNet", "0.15.0")] 58 [PluginDependency("HeuristicLab.DiffSharp", "0.7.7")]58 //[PluginDependency("HeuristicLab.DiffSharp", "0.7.7")] 59 59 public class HeuristicLabProblemsDataAnalysisSymbolicPlugin : PluginBase { 60 60 }
Note: See TracChangeset
for help on using the changeset viewer.