From 53edceccf466140f08a1b42986acc4b0ab875964 Mon Sep 17 00:00:00 2001 From: Oceania2018 Date: Thu, 25 Jul 2019 17:11:40 -0500 Subject: [PATCH 1/6] change bottleneck file to raw image as input for transfer learning. --- .../ImageProcessing/RetrainImageClassifier.cs | 38 +++++++++++++++---- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/test/TensorFlowNET.Examples/ImageProcessing/RetrainImageClassifier.cs b/test/TensorFlowNET.Examples/ImageProcessing/RetrainImageClassifier.cs index 921c3308..4d3a858f 100644 --- a/test/TensorFlowNET.Examples/ImageProcessing/RetrainImageClassifier.cs +++ b/test/TensorFlowNET.Examples/ImageProcessing/RetrainImageClassifier.cs @@ -735,21 +735,43 @@ namespace TensorFlowNET.Examples.ImageProcess var labels = File.ReadAllLines(output_labels); + // predict image + var img_path = Path.Join(image_dir, "roses", "12240303_80d87f77a3_n.jpg"); + var fileBytes = ReadTensorFromImageFile(img_path); + + // import graph and variables var graph = Graph.ImportFromPB(output_graph, ""); - Tensor input_layer = graph.OperationByName("input/BottleneckInputPlaceholder"); - Tensor output_layer = graph.OperationByName("final_result"); + Tensor input = graph.OperationByName("Placeholder"); + Tensor output = graph.OperationByName("final_result"); with(tf.Session(graph), sess => { - var bottleneck_path = Path.Join(bottleneck_dir, "roses", "12240303_80d87f77a3_n.jpg_https~tfhub.dev~google~imagenet~inception_v3~feature_vector~3.txt"); - var bottleneck_string = File.ReadAllText(bottleneck_path); - var bottleneck_values = Array.ConvertAll(bottleneck_string.Split(','), x => float.Parse(x)); - var nd = np.array(bottleneck_values).reshape(1, 2048); - var result = sess.run(output_layer, new FeedItem(input_layer, nd)); + var result = sess.run(output, new FeedItem(input, fileBytes)); var prob = np.squeeze(result); var idx = np.argmax(prob); - print($"Prediction result: [{labels[idx]} {prob[idx][0]}] for {bottleneck_path}."); + print($"Prediction result: [{labels[idx]} {prob[idx][0]}] for {img_path}."); + }); + } + + private NDArray ReadTensorFromImageFile(string file_name, + int input_height = 299, + int input_width = 299, + int input_mean = 0, + int input_std = 255) + { + return with(tf.Graph().as_default(), graph => + { + var file_reader = tf.read_file(file_name, "file_reader"); + var image_reader = tf.image.decode_jpeg(file_reader, channels: 3, name: "jpeg_reader"); + var caster = tf.cast(image_reader, tf.float32); + var dims_expander = tf.expand_dims(caster, 0); + var resize = tf.constant(new int[] { input_height, input_width }); + var bilinear = tf.image.resize_bilinear(dims_expander, resize); + var sub = tf.subtract(bilinear, new float[] { input_mean }); + var normalized = tf.divide(sub, new float[] { input_std }); + + return with(tf.Session(graph), sess => sess.run(normalized)); }); } From 83361f7c974c98fcadcd8cdf00edd652179aa888 Mon Sep 17 00:00:00 2001 From: Esther Hu <33488376+Esther2013@users.noreply.github.com> Date: Thu, 25 Jul 2019 17:23:11 -0500 Subject: [PATCH 2/6] remove unnecessary projects (#316) --- .../TensorFlowNET.Benchmark.csproj | 20 ++++++ test/KerasNET.Example/Keras.Example.csproj | 23 ------- test/KerasNET.Example/Keras.cs | 61 ------------------- test/KerasNET.Example/packages.config | 10 --- test/KerasNET.Test/Keras.UnitTest.csproj | 40 ------------ test/KerasNET.Test/KerasTests.cs | 26 -------- test/KerasNET.Test/packages.config | 11 ---- test/TensorFlowHub.Examples/Program.cs | 12 ---- .../TensorFlowHub.Examples.csproj | 16 ----- 9 files changed, 20 insertions(+), 199 deletions(-) create mode 100644 src/TensorFlowNet.Benchmarks/TensorFlowNET.Benchmark.csproj delete mode 100644 test/KerasNET.Example/Keras.Example.csproj delete mode 100644 test/KerasNET.Example/Keras.cs delete mode 100644 test/KerasNET.Example/packages.config delete mode 100644 test/KerasNET.Test/Keras.UnitTest.csproj delete mode 100644 test/KerasNET.Test/KerasTests.cs delete mode 100644 test/KerasNET.Test/packages.config delete mode 100644 test/TensorFlowHub.Examples/Program.cs delete mode 100644 test/TensorFlowHub.Examples/TensorFlowHub.Examples.csproj diff --git a/src/TensorFlowNet.Benchmarks/TensorFlowNET.Benchmark.csproj b/src/TensorFlowNet.Benchmarks/TensorFlowNET.Benchmark.csproj new file mode 100644 index 00000000..a0af6db4 --- /dev/null +++ b/src/TensorFlowNet.Benchmarks/TensorFlowNET.Benchmark.csproj @@ -0,0 +1,20 @@ + + + + Exe + netcoreapp2.2 + + + + + + + + + + + + + + + diff --git a/test/KerasNET.Example/Keras.Example.csproj b/test/KerasNET.Example/Keras.Example.csproj deleted file mode 100644 index 14fa0138..00000000 --- a/test/KerasNET.Example/Keras.Example.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - - Exe - netcoreapp2.2 - false - Keras.Example.Program - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/test/KerasNET.Example/Keras.cs b/test/KerasNET.Example/Keras.cs deleted file mode 100644 index f85fe127..00000000 --- a/test/KerasNET.Example/Keras.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Collections.Generic; -using Tensorflow; -using Keras.Layers; -using NumSharp; - -namespace Keras.Example -{ - class Program - { - static void Main(string[] args) - { - Console.WriteLine("================================== Keras =================================="); - - #region data - var batch_size = 1000; - var (X, Y) = XOR(batch_size); - //var (X, Y, batch_size) = (np.array(new float[,]{{1, 0 },{1, 1 },{0, 0 },{0, 1 }}), np.array(new int[] { 0, 1, 1, 0 }), 4); - #endregion - - #region features - var (features, labels) = (new Tensor(X), new Tensor(Y)); - var num_steps = 10000; - #endregion - - #region model - var m = new Model(); - - //m.Add(new Dense(8, name: "Hidden", activation: tf.nn.relu())).Add(new Dense(1, name:"Output")); - - m.Add( - new ILayer[] { - new Dense(8, name: "Hidden_1", activation: tf.nn.relu()), - new Dense(1, name: "Output") - }); - - m.train(num_steps, (X, Y)); - #endregion - - Console.ReadKey(); - } - static (NDArray, NDArray) XOR(int samples) - { - var X = new List(); - var Y = new List(); - var r = new Random(); - for (int i = 0; i < samples; i++) - { - var x1 = (float)r.Next(0, 2); - var x2 = (float)r.Next(0, 2); - var y = 0.0f; - if (x1 == x2) - y = 1.0f; - X.Add(new float[] { x1, x2 }); - Y.Add(y); - } - - return (np.array(X.ToArray()), np.array(Y.ToArray())); - } - } -} diff --git a/test/KerasNET.Example/packages.config b/test/KerasNET.Example/packages.config deleted file mode 100644 index e7c17277..00000000 --- a/test/KerasNET.Example/packages.config +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/test/KerasNET.Test/Keras.UnitTest.csproj b/test/KerasNET.Test/Keras.UnitTest.csproj deleted file mode 100644 index e5956a96..00000000 --- a/test/KerasNET.Test/Keras.UnitTest.csproj +++ /dev/null @@ -1,40 +0,0 @@ - - - - netcoreapp2.2 - - false - - Keras.UnitTest - - Keras.UnitTest - - - - Exe - - - - - - DEBUG;TRACE - true - - - - true - - - - - - - - - - - - - - - diff --git a/test/KerasNET.Test/KerasTests.cs b/test/KerasNET.Test/KerasTests.cs deleted file mode 100644 index 05cde48c..00000000 --- a/test/KerasNET.Test/KerasTests.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Tensorflow; -using Keras.Layers; -using NumSharp; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Keras.Test -{ - [TestClass] - public class BaseTests - { - [TestMethod] - public void Dense_Tensor_ShapeTest() - { - var dense_1 = new Dense(1, name: "dense_1", activation: tf.nn.relu()); - var input = new Tensor(np.array(new int[] { 3 })); - dense_1.__build__(input.TensorShape); - var outputShape = dense_1.output_shape(input.TensorShape); - var a = (int[])(outputShape.Dimensions); - var b = (int[])(new int[] { 1 }); - var _a = np.array(a); - var _b = np.array(b); - - Assert.IsTrue(np.array_equal(_a, _b)); - } - } -} diff --git a/test/KerasNET.Test/packages.config b/test/KerasNET.Test/packages.config deleted file mode 100644 index 7e0fea67..00000000 --- a/test/KerasNET.Test/packages.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/test/TensorFlowHub.Examples/Program.cs b/test/TensorFlowHub.Examples/Program.cs deleted file mode 100644 index 3fdbad12..00000000 --- a/test/TensorFlowHub.Examples/Program.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace TensorFlowHub.Examples -{ - class Program - { - static void Main(string[] args) - { - Console.WriteLine("Hello World!"); - } - } -} diff --git a/test/TensorFlowHub.Examples/TensorFlowHub.Examples.csproj b/test/TensorFlowHub.Examples/TensorFlowHub.Examples.csproj deleted file mode 100644 index ae01aa36..00000000 --- a/test/TensorFlowHub.Examples/TensorFlowHub.Examples.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - - Exe - netcoreapp2.2 - - - - - - - - - - - From 09345b9a8235ca68c880ac9cb3cf56638bded73f Mon Sep 17 00:00:00 2001 From: Johann Dirry Date: Fri, 26 Jul 2019 02:58:12 +0200 Subject: [PATCH 3/6] implementing some additional methods (#317) --- src/TensorFlowNET.Core/APIs/tf.ops.cs | 12 +- .../Learn/Estimators/tensor_signature.cs | 39 ++++ .../Framework/sparse_tensor.py.cs | 13 +- .../Framework/tensor_shape.cs | 34 +++ .../Operations/resource_variable_ops.cs | 57 ++++- src/TensorFlowNET.Core/Tensors/Tensor.cs | 5 +- src/TensorFlowNET.Core/Tensors/dtypes.cs | 5 + src/TensorFlowNET.Core/Tensors/tensor_util.cs | 6 + .../Variables/RefVariable.cs | 2 + .../Variables/gen_state_ops.py.cs | 204 +++++++++--------- src/TensorFlowNET.Core/Variables/state_ops.cs | 162 +++++++------- src/TensorFlowNET.Core/tf.cs | 2 +- 12 files changed, 349 insertions(+), 192 deletions(-) create mode 100644 src/TensorFlowNET.Core/Contrib/Learn/Estimators/tensor_signature.cs create mode 100644 src/TensorFlowNET.Core/Framework/tensor_shape.cs diff --git a/src/TensorFlowNET.Core/APIs/tf.ops.cs b/src/TensorFlowNET.Core/APIs/tf.ops.cs index 51189bda..dbd1b246 100644 --- a/src/TensorFlowNET.Core/APIs/tf.ops.cs +++ b/src/TensorFlowNET.Core/APIs/tf.ops.cs @@ -18,8 +18,11 @@ namespace Tensorflow { public static partial class tf { - public static object get_collection(string key, string scope = "") => get_default_graph() - .get_collection(key, scope: scope); + public static Tensor assign(Tensor @ref, object value, bool validate_shape = true, bool use_locking = true, string name = null) + => state_ops.assign(@ref, value, validate_shape, use_locking, name); + + public static object get_collection(string key, string scope = "") + => get_default_graph().get_collection(key, scope: scope); /// /// Returns a context manager that creates hierarchical names for operations. @@ -28,8 +31,7 @@ namespace Tensorflow /// The default name to use if the name argument is None. /// The list of Tensor arguments that are passed to the op function. /// The scope name. - public static ops.NameScope name_scope(string name, - string default_name = "", - object values = null) => new ops.NameScope(name, default_name, values); + public static ops.NameScope name_scope(string name, string default_name = "", object values = null) + => new ops.NameScope(name, default_name, values); } } diff --git a/src/TensorFlowNET.Core/Contrib/Learn/Estimators/tensor_signature.cs b/src/TensorFlowNET.Core/Contrib/Learn/Estimators/tensor_signature.cs new file mode 100644 index 00000000..cf53a8dc --- /dev/null +++ b/src/TensorFlowNET.Core/Contrib/Learn/Estimators/tensor_signature.cs @@ -0,0 +1,39 @@ +using System.Linq; +using NumSharp; +using Tensorflow.Framework; + +namespace Tensorflow.Contrib.Learn.Estimators +{ + public static class tensor_signature + { + public static bool is_compatible_with(this Tensor self, Tensor other) + { + bool _shape_is_compatible_0dim(Shape _this, Shape _other) + { + var __other = tensor_shape.as_shape(_other); + if (_this.Dimensions == null || __other.Dimensions == null) + return true; + + if (_this.NDim != __other.NDim) + return false; + + foreach (var (x_dim, y_dim) in _this.Dimensions.Zip(__other.Dimensions, (x_dim, y_dim) => (x_dim, y_dim))) + { + if (x_dim != y_dim) + return false; + } + + return true; + } + + if (other.is_sparse()) + { + return self.dtype.is_compatible_with(other.dtype); + } + + return self.dtype.is_compatible_with(other.dtype) && + _shape_is_compatible_0dim(self.shape, other.shape) && + !self.is_sparse(); + } + } +} diff --git a/src/TensorFlowNET.Core/Framework/sparse_tensor.py.cs b/src/TensorFlowNET.Core/Framework/sparse_tensor.py.cs index 547d4516..8d0ea53b 100644 --- a/src/TensorFlowNET.Core/Framework/sparse_tensor.py.cs +++ b/src/TensorFlowNET.Core/Framework/sparse_tensor.py.cs @@ -1,8 +1,19 @@ namespace Tensorflow.Framework { - public static class SparseTensor + public interface _TensorLike + { } + + public class SparseTensor : CompositeTensor, _TensorLike { private static Tensor _dense_shape { get; set; } } + + public static class sparse_tensor + { + public static bool is_sparse(this _TensorLike x) + { + return x is SparseTensor; + } + } } diff --git a/src/TensorFlowNET.Core/Framework/tensor_shape.cs b/src/TensorFlowNET.Core/Framework/tensor_shape.cs new file mode 100644 index 00000000..4972c1b4 --- /dev/null +++ b/src/TensorFlowNET.Core/Framework/tensor_shape.cs @@ -0,0 +1,34 @@ +using System; +using System.Linq; +using System.Text; +using NumSharp; +using Tensorflow.Contrib.Learn.Estimators; + +namespace Tensorflow.Framework +{ + public static class tensor_shape + { + public static void assert_is_compatible_with(this Tensor self, Tensor other) + { + if (!self.is_compatible_with(other)) + { + var selfDim = self.shape + .Aggregate(new StringBuilder("{"), (sb, i) => sb.Append(i).Append(", "), sb => sb.ToString()) + .Replace(", }", "}"); + + var otherDim = other.shape + .Aggregate(new StringBuilder("{"), (sb, i) => sb.Append(i).Append(", "), sb => sb.ToString()) + .Replace(", }", "}"); + + throw new ArgumentException($"Dimensions {selfDim} and {otherDim} are not compatible"); + } + } + + public static TensorShape as_shape(this Shape shape) + { + if (shape is TensorShape tshape) + return tshape; + return new TensorShape(shape); + } + } +} diff --git a/src/TensorFlowNET.Core/Operations/resource_variable_ops.cs b/src/TensorFlowNET.Core/Operations/resource_variable_ops.cs index 416e88b4..41bd0ddf 100644 --- a/src/TensorFlowNET.Core/Operations/resource_variable_ops.cs +++ b/src/TensorFlowNET.Core/Operations/resource_variable_ops.cs @@ -14,12 +14,15 @@ limitations under the License. ******************************************************************************/ +using System; +using Tensorflow.Framework; + namespace Tensorflow { /// /// tensorflow\python\ops\resource_variable_ops.py /// - public class resource_variable_ops + public static class resource_variable_ops { public static ITensorOrOperation shape_safe_assign_variable_handle(Tensor handle, int[] shape, Tensor value, string name = null) { @@ -29,9 +32,61 @@ namespace Tensorflow name: name); } + /// + /// + /// + /// + /// + /// + /// + /// + /// If `read_value` is `True`, this method will return the new value of the + /// variable after the assignment has completed.Otherwise, when in graph mode + /// it will return the `Operation` that does the assignment, and when in eager + /// mode it will return `None`. + /// + public static Operation assign(this Tensor self, Tensor value, bool use_locking = false, string name = null, bool read_value = true) + { + var value_tensor = ops.convert_to_tensor(value, dtype: self.dtype); + self.assert_is_compatible_with(value_tensor); + var assign_op = gen_resource_variable_ops.assign_variable_op(self, value_tensor, name: name); + if (read_value) + { + return self._lazy_read(assign_op); + } + + return assign_op; + } + + public static Operation _lazy_read(this Tensor self, Operation op) + { + variable_accessed(self); + throw new NotImplementedException(); + } + + public static void variable_accessed(this Tensor variable) + { + throw new NotImplementedException(); + } + public static bool is_resource_variable(VariableV1 var) { return var is ResourceVariable; } + + /// + /// Represents a future for a read of a variable. + /// Pretends to be the tensor if anyone looks. + /// + public class _UnreadVariable : BaseResourceVariable + { + } + + /// + /// A python variable from an existing handle. + /// + public class BaseResourceVariable : VariableV1 + { + } } } diff --git a/src/TensorFlowNET.Core/Tensors/Tensor.cs b/src/TensorFlowNET.Core/Tensors/Tensor.cs index a2a77a7e..e7049e7e 100644 --- a/src/TensorFlowNET.Core/Tensors/Tensor.cs +++ b/src/TensorFlowNET.Core/Tensors/Tensor.cs @@ -19,6 +19,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; +using Tensorflow.Framework; using static Tensorflow.Python; namespace Tensorflow @@ -27,7 +28,7 @@ namespace Tensorflow /// A tensor is a generalization of vectors and matrices to potentially higher dimensions. /// Internally, TensorFlow represents tensors as n-dimensional arrays of base datatypes. /// - public partial class Tensor : IDisposable, ITensorOrOperation + public partial class Tensor : IDisposable, ITensorOrOperation, _TensorLike { private IntPtr _handle; @@ -109,6 +110,8 @@ namespace Tensorflow this.shape = shape.Dimensions; } + public int[] dims => shape; + /// /// number of dimensions /// 0 Scalar (magnitude only) diff --git a/src/TensorFlowNET.Core/Tensors/dtypes.cs b/src/TensorFlowNET.Core/Tensors/dtypes.cs index c809c96b..16b09d05 100644 --- a/src/TensorFlowNET.Core/Tensors/dtypes.cs +++ b/src/TensorFlowNET.Core/Tensors/dtypes.cs @@ -205,5 +205,10 @@ namespace Tensorflow { return (int)type > 100; } + + public static bool is_compatible_with(this TF_DataType self, TF_DataType other) + { + return self.as_datatype_enum() == other.as_datatype_enum(); + } } } diff --git a/src/TensorFlowNET.Core/Tensors/tensor_util.cs b/src/TensorFlowNET.Core/Tensors/tensor_util.cs index 473bb7ca..2153e2d7 100644 --- a/src/TensorFlowNET.Core/Tensors/tensor_util.cs +++ b/src/TensorFlowNET.Core/Tensors/tensor_util.cs @@ -214,6 +214,12 @@ namespace Tensorflow else nparray = Convert.ToString(values); break; + case "Boolean": + if (values.GetType().IsArray) + nparray = np.array((bool[])values, np_dt); + else + nparray = Convert.ToBoolean(values); + break; default: throw new NotImplementedException($"make_tensor_proto: Support for type {np_dt.Name} Not Implemented"); } diff --git a/src/TensorFlowNET.Core/Variables/RefVariable.cs b/src/TensorFlowNET.Core/Variables/RefVariable.cs index d380975e..78a241c2 100644 --- a/src/TensorFlowNET.Core/Variables/RefVariable.cs +++ b/src/TensorFlowNET.Core/Variables/RefVariable.cs @@ -40,6 +40,8 @@ namespace Tensorflow public override string name => _variable.name; + public Tensor eval() => _variable; + public RefVariable(object initial_value = null, bool trainable = true, List collections = null, diff --git a/src/TensorFlowNET.Core/Variables/gen_state_ops.py.cs b/src/TensorFlowNET.Core/Variables/gen_state_ops.py.cs index e1ab9e20..af34a2ba 100644 --- a/src/TensorFlowNET.Core/Variables/gen_state_ops.py.cs +++ b/src/TensorFlowNET.Core/Variables/gen_state_ops.py.cs @@ -12,102 +12,102 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -******************************************************************************/ - -using System.Collections.Generic; -using Tensorflow.Eager; - -namespace Tensorflow -{ - public class gen_state_ops - { - public static OpDefLibrary _op_def_lib = new OpDefLibrary(); - public static Execute _execute = new Execute(); - - /// - /// Holds state in the form of a tensor that persists across steps. - /// Outputs a ref to the tensor state so it may be read or modified. - /// - /// The shape of the variable tensor. - /// The type of elements in the variable tensor. - /// - /// - /// - /// - public static Tensor variable_v2(int[] shape, TF_DataType dtype, string name = null, string container = "", string shared_name = "") - { - var _op = _op_def_lib._apply_op_helper("VariableV2", name: name, args: new { dtype, shape, container, shared_name }); - - var _result = _op.outputs; - var _inputs_flat = _op.inputs; - - var _attrs = new Dictionary(); - _attrs["dtype"] = _op.get_attr("dtype"); - _attrs["shape"] = _op.get_attr("shape"); - _attrs["container"] = _op.get_attr("container"); - _attrs["shared_name"] = _op.get_attr("shared_name"); - - _execute.record_gradient("VariableV2", _inputs_flat, _attrs, _result, name); - - return _result[0]; - } - - /// - /// Update 'ref' by assigning 'value' to it - /// - /// - /// - /// - /// - /// - public static Tensor assign(Tensor @ref, object value, - bool validate_shape = true, - bool use_locking = true, - string name = null) - { - var _op = _op_def_lib._apply_op_helper("Assign", name: name, args: new { @ref, value, validate_shape, use_locking }); - - var _result = _op.outputs; - var _inputs_flat = _op.inputs; - - var _attrs = new Dictionary(); - _attrs["T"] = _op.get_attr("T"); - _attrs["validate_shape"] = _op.get_attr("validate_shape"); - _attrs["use_locking"] = _op.get_attr("use_locking"); - - _execute.record_gradient("Assign", _inputs_flat, _attrs, _result, name); - - return _result[0]; - } - +******************************************************************************/ + +using System.Collections.Generic; +using Tensorflow.Eager; + +namespace Tensorflow +{ + public class gen_state_ops + { + public static OpDefLibrary _op_def_lib = new OpDefLibrary(); + public static Execute _execute = new Execute(); + + /// + /// Holds state in the form of a tensor that persists across steps. + /// Outputs a ref to the tensor state so it may be read or modified. + /// + /// The shape of the variable tensor. + /// The type of elements in the variable tensor. + /// + /// + /// + /// + public static Tensor variable_v2(int[] shape, TF_DataType dtype, string name = null, string container = "", string shared_name = "") + { + var _op = _op_def_lib._apply_op_helper("VariableV2", name: name, args: new { dtype, shape, container, shared_name }); + + var _result = _op.outputs; + var _inputs_flat = _op.inputs; + + var _attrs = new Dictionary(); + _attrs["dtype"] = _op.get_attr("dtype"); + _attrs["shape"] = _op.get_attr("shape"); + _attrs["container"] = _op.get_attr("container"); + _attrs["shared_name"] = _op.get_attr("shared_name"); + + _execute.record_gradient("VariableV2", _inputs_flat, _attrs, _result, name); + + return _result[0]; + } + + /// + /// Update 'ref' by assigning 'value' to it + /// + /// + /// + /// + /// + /// + public static Tensor assign(Tensor @ref, object value, + bool validate_shape = true, + bool use_locking = true, + string name = null) + { + var _op = _op_def_lib._apply_op_helper("Assign", name: name, args: new { @ref, value, validate_shape, use_locking }); + + var _result = _op.outputs; + var _inputs_flat = _op.inputs; + + var _attrs = new Dictionary(); + _attrs["T"] = _op.get_attr("T"); + _attrs["validate_shape"] = _op.get_attr("validate_shape"); + _attrs["use_locking"] = _op.get_attr("use_locking"); + + _execute.record_gradient("Assign", _inputs_flat, _attrs, _result, name); + + return _result[0]; + } + public static Tensor assign(RefVariable @ref, object value, bool validate_shape = true, - bool use_locking = true, - string name = null) - { - var _op = _op_def_lib._apply_op_helper("Assign", name: name, args: new { @ref, value, validate_shape, use_locking }); - - var _result = _op.outputs; - var _inputs_flat = _op.inputs; - - var _attrs = new Dictionary(); - _attrs["T"] = _op.get_attr("T"); - _attrs["validate_shape"] = _op.get_attr("validate_shape"); - _attrs["use_locking"] = _op.get_attr("use_locking"); - - _execute.record_gradient("Assign", _inputs_flat, _attrs, _result, name); - - return _result[0]; - } - - public static Tensor assign_sub(RefVariable @ref, - Tensor value, - bool use_locking = false, - string name = null) - { - var _op = _op_def_lib._apply_op_helper("AssignSub", name: name, args: new { @ref, value, use_locking }); - - return _op.outputs[0]; + bool use_locking = true, + string name = null) + { + var _op = _op_def_lib._apply_op_helper("Assign", name: name, args: new { @ref, value, validate_shape, use_locking }); + + var _result = _op.outputs; + var _inputs_flat = _op.inputs; + + var _attrs = new Dictionary(); + _attrs["T"] = _op.get_attr("T"); + _attrs["validate_shape"] = _op.get_attr("validate_shape"); + _attrs["use_locking"] = _op.get_attr("use_locking"); + + _execute.record_gradient("Assign", _inputs_flat, _attrs, _result, name); + + return _result[0]; + } + + public static Tensor assign_sub(RefVariable @ref, + Tensor value, + bool use_locking = false, + string name = null) + { + var _op = _op_def_lib._apply_op_helper("AssignSub", name: name, args: new { @ref, value, use_locking }); + + return _op.outputs[0]; } @@ -125,10 +125,10 @@ namespace Tensorflow // name: A name for the operation(optional). // Returns: // A mutable `Tensor`. Has the same type as `ref`. - public static Tensor assign_add(RefVariable @ref, Tensor value, bool use_locking = false, string name = null) - { - var _op = _op_def_lib._apply_op_helper("AssignAdd", name: name, args: new { @ref, value, use_locking }); - return _op.outputs[0]; + public static Tensor assign_add(RefVariable @ref, Tensor value, bool use_locking = false, string name = null) + { + var _op = _op_def_lib._apply_op_helper("AssignAdd", name: name, args: new { @ref, value, use_locking }); + return _op.outputs[0]; } /// @@ -142,8 +142,8 @@ namespace Tensorflow /// public static Tensor scatter_add(RefVariable @ref, Tensor indices, Tensor updates, bool use_locking = false, string name = null) { - var _op = _op_def_lib._apply_op_helper("ScatterAdd", name: name, args: new { @ref, indices, updates, use_locking }); + var _op = _op_def_lib._apply_op_helper("ScatterAdd", name: name, args: new { @ref, indices, updates, use_locking }); return _op.outputs[0]; - } - } -} + } + } +} diff --git a/src/TensorFlowNET.Core/Variables/state_ops.cs b/src/TensorFlowNET.Core/Variables/state_ops.cs index e89844f9..502c3c1e 100644 --- a/src/TensorFlowNET.Core/Variables/state_ops.cs +++ b/src/TensorFlowNET.Core/Variables/state_ops.cs @@ -12,99 +12,99 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -******************************************************************************/ - -using System; - -namespace Tensorflow -{ - public class state_ops - { - /// - /// Create a variable Operation. - /// - /// - /// - /// - /// - /// - /// - public static Tensor variable_op_v2(int[] shape, - TF_DataType dtype, - string name = "Variable", - string container = "", - string shared_name = "") => gen_state_ops.variable_v2(shape, - dtype, - name: name, - container: container, - shared_name: shared_name); - - public static Tensor assign(Tensor @ref, object value, - bool validate_shape = true, - bool use_locking = true, - string name = null) - { - if (@ref.dtype.is_ref_dtype()) - return gen_state_ops.assign(@ref, - value, - validate_shape: validate_shape, - use_locking: use_locking, - name: name); - throw new NotImplementedException("state_ops.assign"); - //return @ref.assign(value, name: name); - } - - public static Tensor assign(RefVariable @ref, object value, - bool validate_shape = true, - bool use_locking = true, - string name = null) +******************************************************************************/ + +using System; + +namespace Tensorflow +{ + public class state_ops + { + /// + /// Create a variable Operation. + /// + /// + /// + /// + /// + /// + /// + public static Tensor variable_op_v2(int[] shape, + TF_DataType dtype, + string name = "Variable", + string container = "", + string shared_name = "") => gen_state_ops.variable_v2(shape, + dtype, + name: name, + container: container, + shared_name: shared_name); + + public static Tensor assign(Tensor @ref, object value, + bool validate_shape = true, + bool use_locking = true, + string name = null) + { + if (@ref.dtype.is_ref_dtype()) + return gen_state_ops.assign(@ref, + value, + validate_shape: validate_shape, + use_locking: use_locking, + name: name); + + return @ref.assign((Tensor)value, name: name); + } + + public static Tensor assign(RefVariable @ref, object value, + bool validate_shape = true, + bool use_locking = true, + string name = null) { return gen_state_ops.assign(@ref, value, validate_shape: validate_shape, use_locking: use_locking, - name: name); - } - - public static Tensor assign_sub(RefVariable @ref, - Tensor value, - bool use_locking = false, - string name = null) => gen_state_ops.assign_sub(@ref, - value, - use_locking: use_locking, - name: name); - - //"""Update 'ref' by adding 'value' to it. - // - // This operation outputs "ref" after the update is done. - // This makes it easier to chain operations that need to use the reset value. - // - // Args: - // ref: A mutable `Tensor`. Must be one of the following types: - // `float32`, `float64`, `int64`, `int32`, `uint8`, `uint16`, `int16`, - // `int8`, `complex64`, `complex128`, `qint8`, `quint8`, `qint32`, `half`. - // Should be from a `Variable` node. - // value: A `Tensor`. Must have the same type as `ref`. - // The value to be added to the variable. - // use_locking: An optional `bool`. Defaults to `False`. - // If True, the addition will be protected by a lock; - // otherwise the behavior is undefined, but may exhibit less contention. - // name: A name for the operation (optional). + name: name); + } + + public static Tensor assign_sub(RefVariable @ref, + Tensor value, + bool use_locking = false, + string name = null) => gen_state_ops.assign_sub(@ref, + value, + use_locking: use_locking, + name: name); + + //"""Update 'ref' by adding 'value' to it. + // + // This operation outputs "ref" after the update is done. + // This makes it easier to chain operations that need to use the reset value. + // + // Args: + // ref: A mutable `Tensor`. Must be one of the following types: + // `float32`, `float64`, `int64`, `int32`, `uint8`, `uint16`, `int16`, + // `int8`, `complex64`, `complex128`, `qint8`, `quint8`, `qint32`, `half`. + // Should be from a `Variable` node. + // value: A `Tensor`. Must have the same type as `ref`. + // The value to be added to the variable. + // use_locking: An optional `bool`. Defaults to `False`. + // If True, the addition will be protected by a lock; + // otherwise the behavior is undefined, but may exhibit less contention. + // name: A name for the operation (optional). // // Returns: // Same as "ref". Returned as a convenience for operations that want // to use the new value after the variable has been updated. - public static Tensor assign_add(RefVariable @ref, - Tensor value, - bool use_locking = false, - string name = null) => gen_state_ops.assign_add(@ref, value, use_locking: use_locking, name: name); - + public static Tensor assign_add(RefVariable @ref, + Tensor value, + bool use_locking = false, + string name = null) => gen_state_ops.assign_add(@ref, value, use_locking: use_locking, name: name); + public static Tensor scatter_add(RefVariable @ref, Tensor indices, Tensor updates, bool use_locking = false, string name = null) { if (@ref.dtype.is_ref_dtype()) return gen_state_ops.scatter_add(@ref, indices, updates, use_locking: use_locking, name: name); throw new NotImplementedException("scatter_add"); - } - } -} + } + } +} diff --git a/src/TensorFlowNET.Core/tf.cs b/src/TensorFlowNET.Core/tf.cs index 027465bf..b10f41b0 100644 --- a/src/TensorFlowNET.Core/tf.cs +++ b/src/TensorFlowNET.Core/tf.cs @@ -46,7 +46,7 @@ namespace Tensorflow trainable: trainable, validate_shape: validate_shape, name: name, - dtype: TF_DataType.DtInvalid); + dtype: dtype); } public static unsafe Tensor placeholder(TF_DataType dtype, TensorShape shape = null, string name = null) From 6b9f86906fd9e94f1659db39981f1bb26a5a645b Mon Sep 17 00:00:00 2001 From: Kerry Jiang Date: Thu, 25 Jul 2019 18:04:16 -0700 Subject: [PATCH 4/6] got rid off the reference to the TF.NET --- src/TensorFlowHub/MnistDataSet.cs | 6 +++--- src/TensorFlowHub/MnistModelLoader.cs | 6 +++--- src/TensorFlowHub/ModelLoadSetting.cs | 2 +- src/TensorFlowHub/TensorFlowHub.csproj | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/TensorFlowHub/MnistDataSet.cs b/src/TensorFlowHub/MnistDataSet.cs index 65b8ebae..e0717ccb 100644 --- a/src/TensorFlowHub/MnistDataSet.cs +++ b/src/TensorFlowHub/MnistDataSet.cs @@ -12,7 +12,7 @@ namespace Tensorflow.Hub public int EpochsCompleted { get; private set; } public int IndexInEpoch { get; private set; } - public MnistDataSet(NDArray images, NDArray labels, TF_DataType dtype, bool reshape) + public MnistDataSet(NDArray images, NDArray labels, Type dataType, bool reshape) { EpochsCompleted = 0; IndexInEpoch = 0; @@ -20,11 +20,11 @@ namespace Tensorflow.Hub NumOfExamples = images.shape[0]; images = images.reshape(images.shape[0], images.shape[1] * images.shape[2]); - images.astype(dtype.as_numpy_datatype()); + images.astype(dataType); images = np.multiply(images, 1.0f / 255.0f); Data = images; - labels.astype(dtype.as_numpy_datatype()); + labels.astype(dataType); Labels = labels; } } diff --git a/src/TensorFlowHub/MnistModelLoader.cs b/src/TensorFlowHub/MnistModelLoader.cs index 670fb0ac..7c4ff109 100644 --- a/src/TensorFlowHub/MnistModelLoader.cs +++ b/src/TensorFlowHub/MnistModelLoader.cs @@ -81,7 +81,7 @@ namespace Tensorflow.Hub trainImages = trainImages[np.arange(validationSize, end)]; trainLabels = trainLabels[np.arange(validationSize, end)]; - var dtype = setting.DtType; + var dtype = setting.DataType; var reshape = setting.ReShape; var train = new MnistDataSet(trainImages, trainLabels, dtype, reshape); @@ -100,7 +100,7 @@ namespace Tensorflow.Hub { var magic = Read32(bytestream); if (magic != 2051) - throw new ValueError($"Invalid magic number {magic} in MNIST image file: {file}"); + throw new Exception($"Invalid magic number {magic} in MNIST image file: {file}"); var num_images = Read32(bytestream); num_images = limit == null ? num_images : Math.Min(num_images, (uint)limit); @@ -128,7 +128,7 @@ namespace Tensorflow.Hub { var magic = Read32(bytestream); if (magic != 2049) - throw new ValueError($"Invalid magic number {magic} in MNIST label file: {file}"); + throw new Exception($"Invalid magic number {magic} in MNIST label file: {file}"); var num_items = Read32(bytestream); num_items = limit == null ? num_items : Math.Min(num_items, (uint)limit); diff --git a/src/TensorFlowHub/ModelLoadSetting.cs b/src/TensorFlowHub/ModelLoadSetting.cs index 91b4059c..89e46748 100644 --- a/src/TensorFlowHub/ModelLoadSetting.cs +++ b/src/TensorFlowHub/ModelLoadSetting.cs @@ -9,7 +9,7 @@ namespace Tensorflow.Hub { public string TrainDir { get; set; } public bool OneHot { get; set; } - public TF_DataType DtType { get; set; } = TF_DataType.TF_FLOAT; + public Type DataType { get; set; } = typeof(float); public bool ReShape { get; set; } public int ValidationSize { get; set; } = 5000; public int? TrainSize { get; set; } diff --git a/src/TensorFlowHub/TensorFlowHub.csproj b/src/TensorFlowHub/TensorFlowHub.csproj index 9288ad1b..ccdcef5a 100644 --- a/src/TensorFlowHub/TensorFlowHub.csproj +++ b/src/TensorFlowHub/TensorFlowHub.csproj @@ -4,6 +4,6 @@ netstandard2.0 - + From 3047277a04e3d5733180be5323a61b33a8fb35b9 Mon Sep 17 00:00:00 2001 From: Kerry Jiang Date: Thu, 25 Jul 2019 18:17:42 -0700 Subject: [PATCH 5/6] updated project file for packaging --- src/TensorFlowHub/TensorFlowHub.csproj | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/TensorFlowHub/TensorFlowHub.csproj b/src/TensorFlowHub/TensorFlowHub.csproj index ccdcef5a..5e1e29a7 100644 --- a/src/TensorFlowHub/TensorFlowHub.csproj +++ b/src/TensorFlowHub/TensorFlowHub.csproj @@ -2,8 +2,17 @@ Tensorflow.Hub netstandard2.0 + 0.0.1 + SciSharp + SciSharp STACK + Apache 2.0 + https://github.com/SciSharp/TensorFlow.NET + git + http://scisharpstack.org + TensorFlow, Training model + TensorFlow Hub is a library to foster the publication, discovery, and consumption of reusable parts of machine learning models. - + \ No newline at end of file From 49c8262a2c454e6466f120ab6d98f501af737f01 Mon Sep 17 00:00:00 2001 From: Oceania2018 Date: Thu, 25 Jul 2019 20:36:31 -0500 Subject: [PATCH 6/6] Release SciSharp.TensorFlowHub v0.0.1. --- src/TensorFlowHub/TensorFlowHub.csproj | 8 ++++++-- src/TensorFlowText/TensorFlowText.csproj | 13 +++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/TensorFlowHub/TensorFlowHub.csproj b/src/TensorFlowHub/TensorFlowHub.csproj index 5e1e29a7..b945c373 100644 --- a/src/TensorFlowHub/TensorFlowHub.csproj +++ b/src/TensorFlowHub/TensorFlowHub.csproj @@ -3,14 +3,18 @@ Tensorflow.Hub netstandard2.0 0.0.1 - SciSharp + Kerry Jiang SciSharp STACK Apache 2.0 https://github.com/SciSharp/TensorFlow.NET git http://scisharpstack.org - TensorFlow, Training model + TensorFlow, SciSharp, MachineLearning TensorFlow Hub is a library to foster the publication, discovery, and consumption of reusable parts of machine learning models. + SciSharp.TensorFlowHub + true + 1. Add MNIST loader. + https://avatars3.githubusercontent.com/u/44989469?s=200&v=4 diff --git a/src/TensorFlowText/TensorFlowText.csproj b/src/TensorFlowText/TensorFlowText.csproj index 2bd48b21..92fee8a8 100644 --- a/src/TensorFlowText/TensorFlowText.csproj +++ b/src/TensorFlowText/TensorFlowText.csproj @@ -2,6 +2,19 @@ netcoreapp2.2 + true + SciSharp.TensorFlowText + 0.0.1 + Haiping Chen + SciSharp STACK + TensorFlowText + TensorFlow Text provides a collection of text related classes and ops ready to use with TensorFlow 2.0. The library can perform the preprocessing regularly required by text-based models, and includes other features useful for sequence modeling not provided by core TensorFlow. + Apache 2.0 + http://scisharpstack.org + https://github.com/SciSharp/TensorFlow.NET + TensorFlow, SciSharp + git + https://avatars3.githubusercontent.com/u/44989469?s=200&v=4