diff --git a/src/TensorFlowNET.Core/APIs/tf.nn.cs b/src/TensorFlowNET.Core/APIs/tf.nn.cs index 7ca290fd..661717eb 100644 --- a/src/TensorFlowNET.Core/APIs/tf.nn.cs +++ b/src/TensorFlowNET.Core/APIs/tf.nn.cs @@ -6,6 +6,12 @@ namespace Tensorflow { public static partial class tf { - public static nn_impl nn => new nn_impl(); + public static class nn + { + public static (Tensor, Tensor) moments(Tensor x, + int[] axes, + string name = null, + bool keep_dims = false) => nn_impl.moments(x, axes, name: name, keep_dims: keep_dims); + } } } diff --git a/src/TensorFlowNET.Core/Operations/gen_math_ops.cs b/src/TensorFlowNET.Core/Operations/gen_math_ops.cs index 24d7607b..33ed4213 100644 --- a/src/TensorFlowNET.Core/Operations/gen_math_ops.cs +++ b/src/TensorFlowNET.Core/Operations/gen_math_ops.cs @@ -22,7 +22,7 @@ namespace Tensorflow /// A `Tensor`. Has the same type as `input`. public static Tensor mean(Tensor input, Tensor axis, bool keep_dims= false, string name = null) { - var _op = _op_def_lib._apply_op_helper("Mean", name, args: new { input, axis }); + var _op = _op_def_lib._apply_op_helper("Mean", name, args: new { input, reduction_indices = axis, keep_dims = keep_dims }); return _op.outputs[0]; } diff --git a/src/TensorFlowNET.Core/Operations/math_ops.py.cs b/src/TensorFlowNET.Core/Operations/math_ops.py.cs index 8e87e388..fb9d097a 100644 --- a/src/TensorFlowNET.Core/Operations/math_ops.py.cs +++ b/src/TensorFlowNET.Core/Operations/math_ops.py.cs @@ -39,7 +39,7 @@ namespace Tensorflow { var r = _ReductionDims(input_tensor, new Tensor(axis)); var m = gen_math_ops.mean(input_tensor, r); - return _may_reduce_to_scalar(keepdims, m); + return _may_reduce_to_scalar(keepdims,axis, m); } /// /// Returns (x - y)(x - y) element-wise. @@ -117,6 +117,12 @@ namespace Tensorflow return output; } + private static Tensor _may_reduce_to_scalar(bool keepdims, int[] axos, Tensor output) + { + output.shape = new long[0]; + return output; + } + private static Tensor _ReductionDims(Tensor x, Tensor axis) { if (axis != null) @@ -130,6 +136,24 @@ namespace Tensorflow } } + private static int[] _ReductionDims(Tensor x, int[] axis) + { + if (axis != null) + { + return axis; + } + else + { + var rank = array_ops.rank(x); + if (rank != null) + { + // return constant_op.constant(); + } + // return range(0, rank, 1); + throw new NotFiniteNumberException(); + } + } + public static Tensor range(object start, object limit = null, object delta = null, TF_DataType dtype = TF_DataType.DtInvalid, string name = "range" ) { if(limit == null) diff --git a/src/TensorFlowNET.Core/Operations/nn_impl.py.cs b/src/TensorFlowNET.Core/Operations/nn_impl.py.cs index 1e6ff3be..262424f4 100644 --- a/src/TensorFlowNET.Core/Operations/nn_impl.py.cs +++ b/src/TensorFlowNET.Core/Operations/nn_impl.py.cs @@ -14,13 +14,12 @@ namespace Tensorflow /// Name used to scope the operations that compute the moments. /// Produce moments with the same dimensionality as the input. /// Two `Tensor` objects: `mean` and `variance`. - public Tuple moments(Tensor x, + public static (Tensor, Tensor) moments(Tensor x, int[] axes, string name = null, bool keep_dims = false) { - Tuple t = null; - with(new ops.name_scope(name, "moments", new { x, axes }), scope => + return with(new ops.name_scope(name, "moments", new { x, axes }), scope => { // The dynamic range of fp16 is too limited to support the collection of // sufficient statistics. As a workaround we simply perform the operations @@ -40,15 +39,10 @@ namespace Tensorflow } // TODO: if x.dtype == dtypes.float16: if (x.dtype == TF_DataType.TF_FLOAT) - { - t = Tuple.Create(math_ops.cast(mean, x.dtype), math_ops.cast(variance, x.dtype)); - return; - } - else { - t = Tuple.Create(mean, variance); - } + return (math_ops.cast(mean, x.dtype), math_ops.cast(variance, x.dtype)); + else + return (mean, variance); }); - return t; } } } diff --git a/test/TensorFlowNET.Examples/NaiveBayesClassifier.cs b/test/TensorFlowNET.Examples/NaiveBayesClassifier.cs index 11cb726a..68a3c438 100644 --- a/test/TensorFlowNET.Examples/NaiveBayesClassifier.cs +++ b/test/TensorFlowNET.Examples/NaiveBayesClassifier.cs @@ -19,7 +19,6 @@ namespace TensorFlowNET.Examples // var X = np.array(new float[][] { new float[] { 1.0f, 1.0f}, new float[] { 2.0f, 2.0f }, new float[] { -1.0f, -1.0f }, new float[] { -2.0f, -2.0f }, new float[] { 1.0f, -1.0f }, new float[] { 2.0f, -2.0f }, }); var X = np.array(new float[][] { new float[] { 1.0f, 1.0f }, new float[] { 2.0f, 2.0f }, new float[] { -1.0f, -1.0f }, new float[] { -2.0f, -2.0f }, new float[] { 1.0f, -1.0f }, new float[] { 2.0f, -2.0f }, }); var y = np.array(0,0,1,1,2,2); - fit(X, y); // Create a regular grid and classify each point @@ -28,12 +27,12 @@ namespace TensorFlowNET.Examples public void fit(NDArray X, NDArray y) { NDArray unique_y = y.unique(); - - Dictionary> dic = new Dictionary>(); + + Dictionary>> dic = new Dictionary>>(); // Init uy in dic foreach (int uy in unique_y.Data()) { - dic.Add(uy, new List()); + dic.Add(uy, new List>()); } // Separate training points by class // Shape : nb_classes * nb_samples * nb_features @@ -41,28 +40,35 @@ namespace TensorFlowNET.Examples for (int i = 0; i < y.size; i++) { long curClass = (long)y[i]; - List l = dic[curClass]; - l.Add(X[i] as NDArray); + List> l = dic[curClass]; + List pair = new List(); + pair.Add((float)X[i,0]); + pair.Add((float)X[i, 1]); + l.Add(pair); if (l.Count > maxCount) { maxCount = l.Count; } dic[curClass] = l; } - NDArray points_by_class = np.zeros(new int[] { dic.Count, maxCount, X.shape[1] }); - foreach (KeyValuePair> kv in dic) + float[,,] points = new float[dic.Count, maxCount, X.shape[1]]; + foreach (KeyValuePair>> kv in dic) { - var cls = kv.Value.ToArray(); - for (int i = 0; i < dic.Count; i++) + int j = (int) kv.Key; + for (int i = 0; i < maxCount; i++) { - points_by_class[i] = dic[i]; + for (int k = 0; k < X.shape[1]; k++) + { + points[j, i, k] = kv.Value[i][k]; + } } - } + } + NDArray points_by_class = np.array(points); // estimate mean and variance for each class / feature // shape : nb_classes * nb_features var cons = tf.constant(points_by_class); - Tuple tup = tf.nn.moments(cons, new int[]{1}); + var tup = tf.nn.moments(cons, new int[]{1}); var mean = tup.Item1; var variance = tup.Item2; // Create a 3x2 univariate normal distribution with the diff --git a/test/TensorFlowNET.Examples/TensorFlowNET.Examples.csproj b/test/TensorFlowNET.Examples/TensorFlowNET.Examples.csproj index c6c052fb..60506b85 100644 --- a/test/TensorFlowNET.Examples/TensorFlowNET.Examples.csproj +++ b/test/TensorFlowNET.Examples/TensorFlowNET.Examples.csproj @@ -20,6 +20,9 @@ C:\Program Files\dotnet\sdk\NuGetFallbackFolder\newtonsoft.json\9.0.1\lib\netstandard1.0\Newtonsoft.Json.dll + + C:\Users\bpeng\Desktop\BoloReborn\NumSharp\src\NumSharp.Core\bin\Debug\netstandard2.0\NumSharp.Core.dll +