Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/09/20 14:01:09 (4 years ago)
Author:
pfleck
Message:

#3040

  • Switched whole TF-graph to float (Adam optimizer won't work with double).
  • Added progress and cancellation support for TF-const opt.
  • Added optional logging with console and/or file for later plotting.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToTensorConverter.cs

    r17493 r17502  
    2929using Tensorflow;
    3030using static Tensorflow.Binding;
    31 using DoubleVector = MathNet.Numerics.LinearAlgebra.Vector<double>;
    3231
    3332namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
    3433  public class TreeToTensorConverter {
    3534
    36     #region helper class
    37     public class DataForVariable {
    38       public readonly string variableName;
    39       public readonly string variableValue; // for factor vars
    40 
    41       public DataForVariable(string varName, string varValue) {
    42         this.variableName = varName;
    43         this.variableValue = varValue;
    44       }
    45 
    46       public override bool Equals(object obj) {
    47         var other = obj as DataForVariable;
    48         if (other == null) return false;
    49         return other.variableName.Equals(this.variableName) &&
    50                other.variableValue.Equals(this.variableValue);
    51       }
    52 
    53       public override int GetHashCode() {
    54         return variableName.GetHashCode() ^ variableValue.GetHashCode();
    55       }
    56     }
    57     #endregion
     35    private static readonly TF_DataType DataType = tf.float32;
    5836
    5937    public static bool TryConvert(ISymbolicExpressionTree tree, int numRows, Dictionary<string, int> variableLengths,
    6038      bool makeVariableWeightsVariable, bool addLinearScalingTerms,
    61       out Tensor graph, out Dictionary<Tensor, string> parameters, out List<Tensor> variables
    62 /*, out double[] initialConstants*/) {
     39      out Tensor graph, out Dictionary<Tensor, string> parameters, out List<Tensor> variables) {
    6340
    6441      try {
     
    6643        graph = converter.ConvertNode(tree.Root.GetSubtree(0));
    6744
    68         //var parametersEntries = converter.parameters.ToList(); // guarantee same order for keys and values
    69         parameters = converter.parameters; // parametersEntries.Select(kvp => kvp.Value).ToList();
     45        parameters = converter.parameters;
    7046        variables = converter.variables;
    71         //initialConstants = converter.initialConstants.ToArray();
    7247        return true;
    7348      } catch (NotSupportedException) {
     
    7550        parameters = null;
    7651        variables = null;
    77         //initialConstants = null;
    7852        return false;
    7953      }
     
    8559    private readonly bool addLinearScalingTerms;
    8660
    87     //private readonly List<double> initialConstants = new List<double>();
    8861    private readonly Dictionary<Tensor, string> parameters = new Dictionary<Tensor, string>();
    8962    private readonly List<Tensor> variables = new List<Tensor>();
     
    9770
    9871
    99 
    10072    private Tensor ConvertNode(ISymbolicExpressionTreeNode node) {
    10173      if (node.Symbol is Constant) {
    102         var value = ((ConstantTreeNode)node).Value;
    103         //initialConstants.Add(value);
    104 #if EXPLICIT_SHAPE
    105         //var var = (RefVariable)tf.VariableV1(value, name: $"c_{variables.Count}", dtype: tf.float64, shape: new[] { 1, 1 });
     74        var value = (float)((ConstantTreeNode)node).Value;
    10675        var value_arr = np.array(value).reshape(1, 1);
    107         var var = tf.Variable(value_arr, name: $"c_{variables.Count}", dtype: tf.float64);
    108 #endif
    109         //var var = tf.Variable(value, name: $"c_{variables.Count}", dtype: tf.float64/*, shape: new[] { 1, 1 }*/);
     76        var var = tf.Variable(value_arr, name: $"c_{variables.Count}", dtype: DataType);
    11077        variables.Add(var);
    11178        return var;
     
    11885        //var varValue = factorVarNode != null ? factorVarNode.VariableValue : string.Empty;
    11986        //var par = FindOrCreateParameter(parameters, varNode.VariableName, varValue);
    120 #if EXPLICIT_SHAPE
    121         var par = tf.placeholder(tf.float64, new TensorShape(numRows, variableLengths[varNode.VariableName]), name: varNode.VariableName);
    122 #endif
     87        var par = tf.placeholder(DataType, new TensorShape(numRows, variableLengths[varNode.VariableName]), name: varNode.VariableName);
    12388        parameters.Add(par, varNode.VariableName);
    12489
    12590        if (makeVariableWeightsVariable) {
    126           //initialConstants.Add(varNode.Weight);
    127 #if EXPLICIT_SHAPE
    128           //var w = (RefVariable)tf.VariableV1(varNode.Weight, name: $"w_{varNode.VariableName}_{variables.Count}", dtype: tf.float64, shape: new[] { 1, 1 });
    129           var w_arr = np.array(varNode.Weight).reshape(1, 1);
    130           var w = tf.Variable(w_arr, name: $"w_{varNode.VariableName}", dtype: tf.float64);
    131 #endif
    132           //var w = tf.Variable(varNode.Weight, name: $"w_{varNode.VariableName}_{variables.Count}", dtype: tf.float64/*, shape: new[] { 1, 1 }*/);
     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);
    13393          variables.Add(w);
    13494          return w * par;
     
    143103      //  foreach (var variableValue in factorVarNode.Symbol.GetVariableValues(factorVarNode.VariableName)) {
    144104      //    //var par = FindOrCreateParameter(parameters, factorVarNode.VariableName, variableValue);
    145       //    var par = tf.placeholder(tf.float64, new TensorShape(numRows, 1), name: factorVarNode.VariableName);
     105      //    var par = tf.placeholder(DataType, new TensorShape(numRows, 1), name: factorVarNode.VariableName);
    146106      //    parameters.Add(par, factorVarNode.VariableName);
    147107
    148108      //    var value = factorVarNode.GetValue(variableValue);
    149109      //    //initialConstants.Add(value);
    150       //    var wVar = (RefVariable)tf.VariableV1(value, name: $"f_{factorVarNode.VariableName}_{variables.Count}", dtype: tf.float64, shape: new[] { 1, 1 });
     110      //    var wVar = (RefVariable)tf.VariableV1(value, name: $"f_{factorVarNode.VariableName}_{variables.Count}", dtype: DataType, shape: new[] { 1, 1 });
    151111      //    //var wVar = tf.Variable(value, name: $"f_{factorVarNode.VariableName}_{variables.Count}"/*, shape: new[] { 1, 1 }*/);
    152112      //    variables.Add(wVar);
     
    159119
    160120      if (node.Symbol is Addition) {
    161         var terms = new List<Tensor>();
    162         foreach (var subTree in node.Subtrees) {
    163           terms.Add(ConvertNode(subTree));
    164         }
    165 
     121        var terms = node.Subtrees.Select(ConvertNode).ToList();
    166122        return terms.Aggregate((a, b) => a + b);
    167123      }
    168124
    169125      if (node.Symbol is Subtraction) {
    170         var terms = new List<Tensor>();
    171         for (int i = 0; i < node.SubtreeCount; i++) {
    172           var t = ConvertNode(node.GetSubtree(i));
    173           if (i > 0) t = -t;
    174           terms.Add(t);
    175         }
    176 
     126        var terms = node.Subtrees.Select(ConvertNode).ToList();
    177127        if (terms.Count == 1) return -terms[0];
    178         else return terms.Aggregate((a, b) => a + b);
     128        return terms.Aggregate((a, b) => a - b);
    179129      }
    180130
    181131      if (node.Symbol is Multiplication) {
    182         var terms = new List<Tensor>();
    183         foreach (var subTree in node.Subtrees) {
    184           terms.Add(ConvertNode(subTree));
    185         }
    186 
    187         if (terms.Count == 1) return terms[0];
    188         else return terms.Aggregate((a, b) => a * b);
     132        var terms = node.Subtrees.Select(ConvertNode).ToList();
     133        return terms.Aggregate((a, b) => a * b);
    189134      }
    190135
    191136      if (node.Symbol is Division) {
    192         var terms = new List<Tensor>();
    193         foreach (var subTree in node.Subtrees) {
    194           terms.Add(ConvertNode(subTree));
    195         }
    196 
    197         if (terms.Count == 1) return 1.0 / terms[0];
    198         else return terms.Aggregate((a, b) => a * (1.0 / b));
     137        var terms = node.Subtrees.Select(ConvertNode).ToList();
     138        if (terms.Count == 1) return 1.0f / terms[0];
     139        return terms.Aggregate((a, b) => a / b);
    199140      }
    200141
     
    207148        var x1 = ConvertNode(node.GetSubtree(0));
    208149        var x2 = ConvertNode(node.GetSubtree(1));
    209         return x1 / tf.pow(1 + x2 * x2, 0.5);
     150        return x1 / tf.pow(1.0f + x2 * x2, 0.5f);
    210151      }
    211152
     
    233174      if (node.Symbol is Cube) {
    234175        return math_ops.pow(
    235           ConvertNode(node.GetSubtree(0)), 3.0);
     176          ConvertNode(node.GetSubtree(0)), 3.0f);
    236177      }
    237178
    238179      if (node.Symbol is CubeRoot) {
    239180        return math_ops.pow(
    240           ConvertNode(node.GetSubtree(0)), 1.0 / 3.0);
     181          ConvertNode(node.GetSubtree(0)), 1.0f / 3.0f);
    241182        // TODO
    242183        // f: x < 0 ? -Math.Pow(-x, 1.0 / 3) : Math.Pow(x, 1.0 / 3),
     
    281222
    282223      if (node.Symbol is StartSymbol) {
     224        Tensor prediction;
    283225        if (addLinearScalingTerms) {
    284226          // scaling variables α, β are given at the beginning of the parameter vector
    285 #if EXPLICIT_SHAPE
    286           //var alpha = (RefVariable)tf.VariableV1(1.0, name: $"alpha_{1.0}", dtype: tf.float64, shape: new[] { 1, 1 });
    287           //var beta = (RefVariable)tf.VariableV1(0.0, name: $"beta_{0.0}", dtype: tf.float64, shape: new[] { 1, 1 });
    288 
    289           var alpha_arr = np.array(1.0).reshape(1, 1);
    290           var alpha = tf.Variable(alpha_arr, name: "alpha", dtype: tf.float64);
    291           var beta_arr = np.array(0.0).reshape(1, 1);
    292           var beta = tf.Variable(beta_arr, name: "beta", dtype: tf.float64);
    293 #endif
    294           //var alpha = tf.Variable(1.0, name: $"alpha_{1.0}", dtype: tf.float64/*, shape: new[] { 1, 1 }*/);
    295           //var beta = tf.Variable(0.0, name: $"beta_{0.0}", dtype: tf.float64/*, shape: new[] { 1, 1 }*/);
     227          var alpha_arr = np.array(1.0f).reshape(1, 1);
     228          var alpha = tf.Variable(alpha_arr, name: "alpha", dtype: DataType);
     229          var beta_arr = np.array(0.0f).reshape(1, 1);
     230          var beta = tf.Variable(beta_arr, name: "beta", dtype: DataType);
    296231          variables.Add(alpha);
    297232          variables.Add(beta);
    298233          var t = ConvertNode(node.GetSubtree(0));
    299           return t * alpha + beta;
    300         } else return ConvertNode(node.GetSubtree(0));
     234          prediction = t * alpha + beta;
     235        } else {
     236          prediction = ConvertNode(node.GetSubtree(0));
     237        }
     238
     239        return tf.reduce_sum(prediction, axis: new[] { 1 });
    301240      }
    302241
Note: See TracChangeset for help on using the changeset viewer.