From 27051792f5ea15bfb79042294362359e2c9ee2cd Mon Sep 17 00:00:00 2001 From: Bo Peng Date: Wed, 6 Mar 2019 14:20:04 -0600 Subject: [PATCH] implemented nn class --- TensorFlow.NET.sln | 6 ++++ src/TensorFlowNET.Core/APIs/tf.nn.cs | 8 ++++- .../Operations/gen_math_ops.cs | 2 +- .../Operations/math_ops.py.cs | 26 ++++++++++++++- .../Operations/nn_impl.py.cs | 16 +++------- .../TensorFlowNET.Core.csproj | 4 +++ .../NaiveBayesClassifier.cs | 32 +++++++++++-------- .../TensorFlowNET.Examples.csproj | 11 +++---- 8 files changed, 72 insertions(+), 33 deletions(-) diff --git a/TensorFlow.NET.sln b/TensorFlow.NET.sln index 880d886b..24afc77e 100644 --- a/TensorFlow.NET.sln +++ b/TensorFlow.NET.sln @@ -13,6 +13,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Utility", "sr EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Visualization", "TensorFlowNET.Visualization\TensorFlowNET.Visualization.csproj", "{4BB2ABD1-635E-41E4-B534-CB5B6A2D754D}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NumSharp.Core", "..\NumSharp\src\NumSharp.Core\NumSharp.Core.csproj", "{268BF0B6-0AA9-4FD3-A245-7AF336F1E3E9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -39,6 +41,10 @@ Global {4BB2ABD1-635E-41E4-B534-CB5B6A2D754D}.Debug|Any CPU.Build.0 = Debug|Any CPU {4BB2ABD1-635E-41E4-B534-CB5B6A2D754D}.Release|Any CPU.ActiveCfg = Release|Any CPU {4BB2ABD1-635E-41E4-B534-CB5B6A2D754D}.Release|Any CPU.Build.0 = Release|Any CPU + {268BF0B6-0AA9-4FD3-A245-7AF336F1E3E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {268BF0B6-0AA9-4FD3-A245-7AF336F1E3E9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {268BF0B6-0AA9-4FD3-A245-7AF336F1E3E9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {268BF0B6-0AA9-4FD3-A245-7AF336F1E3E9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE 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 ed952e53..b0015983 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 3005863c..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/src/TensorFlowNET.Core/TensorFlowNET.Core.csproj b/src/TensorFlowNET.Core/TensorFlowNET.Core.csproj index c4e5891d..01448769 100644 --- a/src/TensorFlowNET.Core/TensorFlowNET.Core.csproj +++ b/src/TensorFlowNET.Core/TensorFlowNET.Core.csproj @@ -51,4 +51,8 @@ Docs: https://tensorflownet.readthedocs.io + + + + 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 e32a8092..28952543 100644 --- a/test/TensorFlowNET.Examples/TensorFlowNET.Examples.csproj +++ b/test/TensorFlowNET.Examples/TensorFlowNET.Examples.csproj @@ -1,4 +1,4 @@ - + Exe @@ -6,11 +6,7 @@ - - - - - + @@ -19,6 +15,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 +