From cd7a36435ac993221893310951f8e1b1ff889a4f Mon Sep 17 00:00:00 2001 From: Bo Peng Date: Wed, 6 Mar 2019 17:33:03 -0600 Subject: [PATCH] implemented NB classifier fit API --- src/TensorFlowNET.Core/APIs/tf.distributions.cs | 14 ++++++++++++++ .../Framework/sparse_tensor.py.cs | 12 ++++++++++++ .../Operations/Distributions/distribution.py.cs | 5 +++-- .../Operations/Distributions/normal.py.cs | 15 ++++++++------- .../Operations/OpDefLibrary.cs | 3 +++ .../Operations/gen_array_ops.cs | 4 ++-- .../Operations/gen_math_ops.cs | 9 ++++++++- .../Operations/math_ops.py.cs | 17 +++++++++-------- src/TensorFlowNET.Core/Operations/nn_impl.py.cs | 6 +++--- .../NaiveBayesClassifier.cs | 3 ++- 10 files changed, 64 insertions(+), 24 deletions(-) create mode 100644 src/TensorFlowNET.Core/APIs/tf.distributions.cs create mode 100644 src/TensorFlowNET.Core/Framework/sparse_tensor.py.cs diff --git a/src/TensorFlowNET.Core/APIs/tf.distributions.cs b/src/TensorFlowNET.Core/APIs/tf.distributions.cs new file mode 100644 index 00000000..884ee926 --- /dev/null +++ b/src/TensorFlowNET.Core/APIs/tf.distributions.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Tensorflow.APIs +{ + public static partial class tf + { + public static class distributions + { + public static Normal(Tensor loc, Tensor scale, bool validate_args = false, bool allow_nan_stats = true, string name = "Normal") => Normal(loc, scale, validate_args = false, allow_nan_stats = true, "Normal"); + } + } +} diff --git a/src/TensorFlowNET.Core/Framework/sparse_tensor.py.cs b/src/TensorFlowNET.Core/Framework/sparse_tensor.py.cs new file mode 100644 index 00000000..718c989b --- /dev/null +++ b/src/TensorFlowNET.Core/Framework/sparse_tensor.py.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Tensorflow.Framework +{ + public static class SparseTensor + { + private static Tensor _dense_shape { get; set; } + + } +} diff --git a/src/TensorFlowNET.Core/Operations/Distributions/distribution.py.cs b/src/TensorFlowNET.Core/Operations/Distributions/distribution.py.cs index 7d9aef11..b2c220a7 100644 --- a/src/TensorFlowNET.Core/Operations/Distributions/distribution.py.cs +++ b/src/TensorFlowNET.Core/Operations/Distributions/distribution.py.cs @@ -4,9 +4,10 @@ using System.Collections.Generic; using System.Text; + namespace Tensorflow { - abstract class _BaseDistribution : Python + class _BaseDistribution : Python { // Abstract base class needed for resolving subclass hierarchy. } @@ -19,7 +20,7 @@ namespace Tensorflow class Distribution : _BaseDistribution { public TF_DataType _dtype {get;set;} - public ReparameterizationType _reparameterization_type {get;set;} + public static ReparameterizationType _reparameterization_type {get;set;} public bool _validate_args {get;set;} public bool _allow_nan_stats {get;set;} public Dictionary _parameters {get;set;} diff --git a/src/TensorFlowNET.Core/Operations/Distributions/normal.py.cs b/src/TensorFlowNET.Core/Operations/Distributions/normal.py.cs index d588fab7..d5b44b06 100644 --- a/src/TensorFlowNET.Core/Operations/Distributions/normal.py.cs +++ b/src/TensorFlowNET.Core/Operations/Distributions/normal.py.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using Tensorflow; namespace Tensorflow { @@ -7,7 +8,7 @@ namespace Tensorflow public Tensor _loc { get; set; } public Tensor _scale { get; set; } - Dictionary parameters = new Dictionary(); + public Dictionary parameters = new Dictionary(); /// /// The Normal distribution with location `loc` and `scale` parameters. /// Mathematical details @@ -24,7 +25,7 @@ namespace Tensorflow /// /// /// - public Normal (Tensor loc, Tensor scale, bool validate_args=false, bool allow_nan_stats=true, string name="Normal") + Normal (Tensor loc, Tensor scale, bool validate_args=false, bool allow_nan_stats=true, string name="Normal") { parameters.Add("name", name); parameters.Add("loc", loc); @@ -39,7 +40,7 @@ namespace Tensorflow this._loc = array_ops.identity(loc, name); this._scale = array_ops.identity(scale, name); base._dtype = this._scale.dtype; - base._reparameterization_type = new ReparameterizationType("FULLY_REPARAMETERIZED"); + // base._reparameterization_type = new ReparameterizationType("FULLY_REPARAMETERIZED"); base._validate_args = validate_args; base._allow_nan_stats = allow_nan_stats; base._parameters = parameters; @@ -56,7 +57,7 @@ namespace Tensorflow /// public Tensor loc() { - return this._loc; + return _loc; } /// /// Distribution parameter for standard deviation." @@ -64,17 +65,17 @@ namespace Tensorflow /// public Tensor scale() { - return this._scale; + return _scale; } public Tensor _batch_shape_tensor() { - return array_ops.broadcast_dynamic_shape(array_ops.shape(this._loc), array_ops.shape(this._scale)); + return array_ops.broadcast_dynamic_shape(array_ops.shape(_loc), array_ops.shape(_scale)); } public Tensor _batch_shape() { - return array_ops.broadcast_static_shape(new Tensor(this._loc.shape), new Tensor(this._scale.shape)); + return array_ops.broadcast_static_shape(new Tensor(_loc.shape), new Tensor(_scale.shape)); } } diff --git a/src/TensorFlowNET.Core/Operations/OpDefLibrary.cs b/src/TensorFlowNET.Core/Operations/OpDefLibrary.cs index 8e6bfba0..a3f7a697 100644 --- a/src/TensorFlowNET.Core/Operations/OpDefLibrary.cs +++ b/src/TensorFlowNET.Core/Operations/OpDefLibrary.cs @@ -305,6 +305,9 @@ namespace Tensorflow case "list(type)": attr_value.List.Type.AddRange((value as IList).Select(x => _MakeType(x, attr_def))); break; + case "list(int)": + attr_value.List.I.AddRange((value as int[]).Select(x => Convert.ToInt64(x))); + break; case "bool": attr_value.B = (bool)value; break; diff --git a/src/TensorFlowNET.Core/Operations/gen_array_ops.cs b/src/TensorFlowNET.Core/Operations/gen_array_ops.cs index 80884393..28b3f0ce 100644 --- a/src/TensorFlowNET.Core/Operations/gen_array_ops.cs +++ b/src/TensorFlowNET.Core/Operations/gen_array_ops.cs @@ -157,7 +157,7 @@ namespace Tensorflow } public static Tensor stop_gradient(Tensor x, string name = null) { - var _op = _op_def_lib._apply_op_helper("StopGradient", name, args: new { x }); + var _op = _op_def_lib._apply_op_helper("StopGradient", name, args: new { input = x, name }); return _op.outputs[0]; } @@ -174,7 +174,7 @@ namespace Tensorflow /// A `Tensor`. Has the same type as `input`. public static Tensor squeeze(Tensor input, int[] axis = null, string name = null) { - var _op = _op_def_lib._apply_op_helper("Squeeze", name, args: new { input, axis, name }); + var _op = _op_def_lib._apply_op_helper("Squeeze", name, args: new { input, squeeze_dims = axis }); return _op.outputs[0]; } diff --git a/src/TensorFlowNET.Core/Operations/gen_math_ops.cs b/src/TensorFlowNET.Core/Operations/gen_math_ops.cs index 33ed4213..0ef8540c 100644 --- a/src/TensorFlowNET.Core/Operations/gen_math_ops.cs +++ b/src/TensorFlowNET.Core/Operations/gen_math_ops.cs @@ -27,6 +27,13 @@ namespace Tensorflow return _op.outputs[0]; } + public static Tensor mean(Tensor input, int[] axis, bool keep_dims = false, string name = null) + { + var _op = _op_def_lib._apply_op_helper("Mean", name, args: new { input, reduction_indices = axis, keep_dims = keep_dims, name }); + + return _op.outputs[0]; + } + public static Tensor add(Tensor x, Tensor y, string name = null) { var _op = _op_def_lib._apply_op_helper("Add", name, args: new { x, y }); @@ -36,7 +43,7 @@ namespace Tensorflow public static Tensor squared_difference(Tensor x, Tensor y, string name = null) { - var _op = _op_def_lib._apply_op_helper("SquaredDifference", name, args: new { x, y }); + var _op = _op_def_lib._apply_op_helper("SquaredDifference", name, args: new { x, y, name }); 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 fb9d097a..c20ba154 100644 --- a/src/TensorFlowNET.Core/Operations/math_ops.py.cs +++ b/src/TensorFlowNET.Core/Operations/math_ops.py.cs @@ -1,4 +1,5 @@ -using System; +using NumSharp.Core; +using System; using System.Collections.Generic; using System.Text; @@ -37,8 +38,8 @@ namespace Tensorflow /// A name for the operation (optional). public static Tensor reduce_mean(Tensor input_tensor, int[] axis = null, bool keepdims = false, string name = null) { - var r = _ReductionDims(input_tensor, new Tensor(axis)); - var m = gen_math_ops.mean(input_tensor, r); + var r = _ReductionDims(input_tensor, axis); + var m = gen_math_ops.mean(input_tensor, (int[]) r, keepdims, name); return _may_reduce_to_scalar(keepdims,axis, m); } /// @@ -135,8 +136,8 @@ namespace Tensorflow return range(0, rank, 1); } } - - private static int[] _ReductionDims(Tensor x, int[] axis) + + private static object _ReductionDims(Tensor x, int[] axis) { if (axis != null) { @@ -147,12 +148,12 @@ namespace Tensorflow var rank = array_ops.rank(x); if (rank != null) { - // return constant_op.constant(); + return constant_op.constant(np.arange(rank), TF_DataType.TF_INT32); } - // return range(0, rank, 1); - throw new NotFiniteNumberException(); + return range(0, rank, 1); } } + public static Tensor range(object start, object limit = null, object delta = null, TF_DataType dtype = TF_DataType.DtInvalid, string name = "range" ) { diff --git a/src/TensorFlowNET.Core/Operations/nn_impl.py.cs b/src/TensorFlowNET.Core/Operations/nn_impl.py.cs index 262424f4..802df5f9 100644 --- a/src/TensorFlowNET.Core/Operations/nn_impl.py.cs +++ b/src/TensorFlowNET.Core/Operations/nn_impl.py.cs @@ -26,19 +26,19 @@ namespace Tensorflow // on 32-bit floats before converting the mean and variance back to fp16 var y = math_ops.cast(x, TF_DataType.TF_FLOAT); // Compute true mean while keeping the dims for proper broadcasting. - var mean = math_ops.reduce_mean(y, axes, keep_dims = true, name = "mean"); + var mean = math_ops.reduce_mean(y, axes, true, name = "mean"); // Sample variance, not unbiased variance // Note: stop_gradient does not change the gradient that gets // backpropagated to the mean from the variance calculation, // because that gradient is zero - var variance = math_ops.reduce_mean(math_ops.reduce_mean(math_ops.square_difference(y, array_ops.stop_gradient(mean)), axes, keep_dims = true, name = "Variance")); + var variance = math_ops.reduce_mean(math_ops.square_difference(y, array_ops.stop_gradient(mean)), axes, true, name = "Variance"); if (!keep_dims) { mean = array_ops.squeeze(mean, axes); variance = array_ops.squeeze(variance, axes); } // TODO: if x.dtype == dtypes.float16: - if (x.dtype == TF_DataType.TF_FLOAT) + if (x.dtype == TF_DataType.TF_HALF) return (math_ops.cast(mean, x.dtype), math_ops.cast(variance, x.dtype)); else return (mean, variance); diff --git a/test/TensorFlowNET.Examples/NaiveBayesClassifier.cs b/test/TensorFlowNET.Examples/NaiveBayesClassifier.cs index 68a3c438..00cd1211 100644 --- a/test/TensorFlowNET.Examples/NaiveBayesClassifier.cs +++ b/test/TensorFlowNET.Examples/NaiveBayesClassifier.cs @@ -71,9 +71,10 @@ namespace TensorFlowNET.Examples 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 // Known mean and variance - // var dist = tf.distributions.Normal(loc=mean, scale=tf.sqrt(variance)); + var dist = tf.distributions.Normal(loc=mean, scale=tf.sqrt(variance)); }