Index: branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToTensorConverter.cs
===================================================================
--- branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToTensorConverter.cs	(revision 17476)
+++ branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToTensorConverter.cs	(revision 17489)
@@ -20,8 +20,11 @@
 #endregion
 
+#define EXPLICIT_SHAPE
+
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using NumSharp;
 using Tensorflow;
 using static Tensorflow.Binding;
@@ -54,5 +57,5 @@
     #endregion
 
-    public static bool TryConvert(ISymbolicExpressionTree tree, int numRows, int? vectorLength,
+    public static bool TryConvert(ISymbolicExpressionTree tree, int numRows, Dictionary<string, int> variableLengths,
       bool makeVariableWeightsVariable, bool addLinearScalingTerms,
       out Tensor graph, out Dictionary<Tensor, string> parameters, out List<Tensor> variables
@@ -60,5 +63,5 @@
 
       try {
-        var converter = new TreeToTensorConverter(numRows, vectorLength, makeVariableWeightsVariable, addLinearScalingTerms);
+        var converter = new TreeToTensorConverter(numRows, variableLengths, makeVariableWeightsVariable, addLinearScalingTerms);
         graph = converter.ConvertNode(tree.Root.GetSubtree(0));
 
@@ -78,5 +81,5 @@
 
     private readonly int numRows;
-    private readonly int? vectorLength;
+    private readonly Dictionary<string, int> variableLengths;
     private readonly bool makeVariableWeightsVariable;
     private readonly bool addLinearScalingTerms;
@@ -86,10 +89,11 @@
     private readonly List<Tensor> variables = new List<Tensor>();
 
-    private TreeToTensorConverter(int numRows, int? vectorLength, bool makeVariableWeightsVariable, bool addLinearScalingTerms) {
+    private TreeToTensorConverter(int numRows, Dictionary<string, int> variableLengths, bool makeVariableWeightsVariable, bool addLinearScalingTerms) {
       this.numRows = numRows;
-      this.vectorLength = vectorLength;
+      this.variableLengths = variableLengths;
       this.makeVariableWeightsVariable = makeVariableWeightsVariable;
       this.addLinearScalingTerms = addLinearScalingTerms;
     }
+
 
 
@@ -98,5 +102,10 @@
         var value = ((ConstantTreeNode)node).Value;
         //initialConstants.Add(value);
-        var var = tf.Variable(value, name: $"c_{variables.Count}", dtype: tf.float64);
+#if EXPLICIT_SHAPE
+        //var var = (RefVariable)tf.VariableV1(value, name: $"c_{variables.Count}", dtype: tf.float64, shape: new[] { 1, 1 });
+        var value_arr = np.array(value).reshape(1, 1);
+        var var = tf.Variable(value_arr, name: $"c_{variables.Count}", dtype: tf.float64);
+#endif
+        //var var = tf.Variable(value, name: $"c_{variables.Count}", dtype: tf.float64/*, shape: new[] { 1, 1 }*/);
         variables.Add(var);
         return var;
@@ -109,13 +118,17 @@
         //var varValue = factorVarNode != null ? factorVarNode.VariableValue : string.Empty;
         //var par = FindOrCreateParameter(parameters, varNode.VariableName, varValue);
-        var shape = vectorLength.HasValue
-          ? new TensorShape(numRows, vectorLength.Value)
-          : new TensorShape(numRows);
-        var par = tf.placeholder(tf.float64, shape: shape, name: varNode.VariableName);
+#if EXPLICIT_SHAPE
+        var par = tf.placeholder(tf.float64, new TensorShape(numRows, variableLengths[varNode.VariableName]), name: varNode.VariableName);
+#endif
         parameters.Add(par, varNode.VariableName);
 
         if (makeVariableWeightsVariable) {
           //initialConstants.Add(varNode.Weight);
-          var w = tf.Variable(varNode.Weight, name: $"w_{varNode.VariableName}_{variables.Count}", dtype: tf.float64);
+#if EXPLICIT_SHAPE
+          //var w = (RefVariable)tf.VariableV1(varNode.Weight, name: $"w_{varNode.VariableName}_{variables.Count}", dtype: tf.float64, shape: new[] { 1, 1 });
+          var w_arr = np.array(varNode.Weight).reshape(1, 1);
+          var w = tf.Variable(w_arr, name: $"w_{varNode.VariableName}", dtype: tf.float64);
+#endif
+          //var w = tf.Variable(varNode.Weight, name: $"w_{varNode.VariableName}_{variables.Count}", dtype: tf.float64/*, shape: new[] { 1, 1 }*/);
           variables.Add(w);
           return w * par;
@@ -125,22 +138,23 @@
       }
 
-      if (node.Symbol is FactorVariable) {
-        var factorVarNode = node as FactorVariableTreeNode;
-        var products = new List<Tensor>();
-        foreach (var variableValue in factorVarNode.Symbol.GetVariableValues(factorVarNode.VariableName)) {
-          //var par = FindOrCreateParameter(parameters, factorVarNode.VariableName, variableValue);
-          var par = tf.placeholder(tf.float64, shape: new TensorShape(numRows), name: factorVarNode.VariableName);
-          parameters.Add(par, factorVarNode.VariableName);
-
-          var value = factorVarNode.GetValue(variableValue);
-          //initialConstants.Add(value);
-          var wVar = tf.Variable(value, name: $"f_{factorVarNode.VariableName}_{variables.Count}");
-          variables.Add(wVar);
-
-          products.add(wVar * par);
-        }
-
-        return products.Aggregate((a, b) => a + b);
-      }
+      //if (node.Symbol is FactorVariable) {
+      //  var factorVarNode = node as FactorVariableTreeNode;
+      //  var products = new List<Tensor>();
+      //  foreach (var variableValue in factorVarNode.Symbol.GetVariableValues(factorVarNode.VariableName)) {
+      //    //var par = FindOrCreateParameter(parameters, factorVarNode.VariableName, variableValue);
+      //    var par = tf.placeholder(tf.float64, new TensorShape(numRows, 1), name: factorVarNode.VariableName);
+      //    parameters.Add(par, factorVarNode.VariableName);
+
+      //    var value = factorVarNode.GetValue(variableValue);
+      //    //initialConstants.Add(value);
+      //    var wVar = (RefVariable)tf.VariableV1(value, name: $"f_{factorVarNode.VariableName}_{variables.Count}", dtype: tf.float64, shape: new[] { 1, 1 });
+      //    //var wVar = tf.Variable(value, name: $"f_{factorVarNode.VariableName}_{variables.Count}"/*, shape: new[] { 1, 1 }*/);
+      //    variables.Add(wVar);
+
+      //    products.add(wVar * par);
+      //  }
+
+      //  return products.Aggregate((a, b) => a + b);
+      //}
 
       if (node.Symbol is Addition) {
@@ -248,5 +262,6 @@
         return tf.reduce_mean(
           ConvertNode(node.GetSubtree(0)),
-          axis: new[] { 1 });
+          axis: new[] { 1 },
+          keepdims: true);
       }
 
@@ -261,5 +276,6 @@
         return tf.reduce_sum(
           ConvertNode(node.GetSubtree(0)),
-          axis: new[] { 1 });
+          axis: new[] { 1 },
+          keepdims: true);
       }
 
@@ -267,6 +283,15 @@
         if (addLinearScalingTerms) {
           // scaling variables α, β are given at the beginning of the parameter vector
-          var alpha = tf.Variable(1.0, name: $"alpha_{1.0}", dtype: tf.float64);
-          var beta = tf.Variable(0.0, name: $"beta_{0.0}", dtype: tf.float64);
+#if EXPLICIT_SHAPE
+          //var alpha = (RefVariable)tf.VariableV1(1.0, name: $"alpha_{1.0}", dtype: tf.float64, shape: new[] { 1, 1 });
+          //var beta = (RefVariable)tf.VariableV1(0.0, name: $"beta_{0.0}", dtype: tf.float64, shape: new[] { 1, 1 });
+
+          var alpha_arr = np.array(1.0).reshape(1, 1);
+          var alpha = tf.Variable(alpha_arr, name: $"alpha", dtype: tf.float64);
+          var beta_arr = np.array(1.0).reshape(1, 1);
+          var beta = tf.Variable(beta_arr, name: $"beta", dtype: tf.float64);
+#endif
+          //var alpha = tf.Variable(1.0, name: $"alpha_{1.0}", dtype: tf.float64/*, shape: new[] { 1, 1 }*/);
+          //var beta = tf.Variable(0.0, name: $"beta_{0.0}", dtype: tf.float64/*, shape: new[] { 1, 1 }*/);
           variables.Add(alpha);
           variables.Add(beta);
@@ -277,17 +302,4 @@
 
       throw new NotSupportedException($"Node symbol {node.Symbol} is not supported.");
-    }
-
-    // for each factor variable value we need a parameter which represents a binary indicator for that variable & value combination
-    // each binary indicator is only necessary once. So we only create a parameter if this combination is not yet available
-    private static Tensor FindOrCreateParameter(Dictionary<DataForVariable, Tensor> parameters, string varName, string varValue = "") {
-      var data = new DataForVariable(varName, varValue);
-
-      if (!parameters.TryGetValue(data, out var par)) {
-        // not found -> create new parameter and entries in names and values lists
-        par = tf.placeholder(tf.float64, shape: new TensorShape(-1), name: varName);
-        parameters.Add(data, par);
-      }
-      return par;
     }
 
