| @@ -12,7 +12,7 @@ namespace Tensorflow.Hub | |||||
| public int EpochsCompleted { get; private set; } | public int EpochsCompleted { get; private set; } | ||||
| public int IndexInEpoch { 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; | EpochsCompleted = 0; | ||||
| IndexInEpoch = 0; | IndexInEpoch = 0; | ||||
| @@ -20,11 +20,11 @@ namespace Tensorflow.Hub | |||||
| NumOfExamples = images.shape[0]; | NumOfExamples = images.shape[0]; | ||||
| images = images.reshape(images.shape[0], images.shape[1] * images.shape[2]); | 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); | images = np.multiply(images, 1.0f / 255.0f); | ||||
| Data = images; | Data = images; | ||||
| labels.astype(dtype.as_numpy_datatype()); | |||||
| labels.astype(dataType); | |||||
| Labels = labels; | Labels = labels; | ||||
| } | } | ||||
| } | } | ||||
| @@ -81,7 +81,7 @@ namespace Tensorflow.Hub | |||||
| trainImages = trainImages[np.arange(validationSize, end)]; | trainImages = trainImages[np.arange(validationSize, end)]; | ||||
| trainLabels = trainLabels[np.arange(validationSize, end)]; | trainLabels = trainLabels[np.arange(validationSize, end)]; | ||||
| var dtype = setting.DtType; | |||||
| var dtype = setting.DataType; | |||||
| var reshape = setting.ReShape; | var reshape = setting.ReShape; | ||||
| var train = new MnistDataSet(trainImages, trainLabels, dtype, reshape); | var train = new MnistDataSet(trainImages, trainLabels, dtype, reshape); | ||||
| @@ -100,7 +100,7 @@ namespace Tensorflow.Hub | |||||
| { | { | ||||
| var magic = Read32(bytestream); | var magic = Read32(bytestream); | ||||
| if (magic != 2051) | 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); | var num_images = Read32(bytestream); | ||||
| num_images = limit == null ? num_images : Math.Min(num_images, (uint)limit); | num_images = limit == null ? num_images : Math.Min(num_images, (uint)limit); | ||||
| @@ -128,7 +128,7 @@ namespace Tensorflow.Hub | |||||
| { | { | ||||
| var magic = Read32(bytestream); | var magic = Read32(bytestream); | ||||
| if (magic != 2049) | 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); | var num_items = Read32(bytestream); | ||||
| num_items = limit == null ? num_items : Math.Min(num_items, (uint)limit); | num_items = limit == null ? num_items : Math.Min(num_items, (uint)limit); | ||||
| @@ -9,7 +9,7 @@ namespace Tensorflow.Hub | |||||
| { | { | ||||
| public string TrainDir { get; set; } | public string TrainDir { get; set; } | ||||
| public bool OneHot { 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 bool ReShape { get; set; } | ||||
| public int ValidationSize { get; set; } = 5000; | public int ValidationSize { get; set; } = 5000; | ||||
| public int? TrainSize { get; set; } | public int? TrainSize { get; set; } | ||||
| @@ -2,8 +2,21 @@ | |||||
| <PropertyGroup> | <PropertyGroup> | ||||
| <RootNamespace>Tensorflow.Hub</RootNamespace> | <RootNamespace>Tensorflow.Hub</RootNamespace> | ||||
| <TargetFramework>netstandard2.0</TargetFramework> | <TargetFramework>netstandard2.0</TargetFramework> | ||||
| <Version>0.0.1</Version> | |||||
| <Authors>Kerry Jiang</Authors> | |||||
| <Company>SciSharp STACK</Company> | |||||
| <Copyright>Apache 2.0</Copyright> | |||||
| <RepositoryUrl>https://github.com/SciSharp/TensorFlow.NET</RepositoryUrl> | |||||
| <RepositoryType>git</RepositoryType> | |||||
| <PackageProjectUrl>http://scisharpstack.org</PackageProjectUrl> | |||||
| <PackageTags>TensorFlow, SciSharp, MachineLearning</PackageTags> | |||||
| <Description>TensorFlow Hub is a library to foster the publication, discovery, and consumption of reusable parts of machine learning models.</Description> | |||||
| <PackageId>SciSharp.TensorFlowHub</PackageId> | |||||
| <GeneratePackageOnBuild>true</GeneratePackageOnBuild> | |||||
| <PackageReleaseNotes>1. Add MNIST loader.</PackageReleaseNotes> | |||||
| <PackageIconUrl>https://avatars3.githubusercontent.com/u/44989469?s=200&v=4</PackageIconUrl> | |||||
| </PropertyGroup> | </PropertyGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| <ProjectReference Include="..\..\src\TensorFlowNET.Core\TensorFlowNET.Core.csproj" /> | |||||
| <PackageReference Include="NumSharp" Version="0.10.6" /> | |||||
| </ItemGroup> | </ItemGroup> | ||||
| </Project> | |||||
| </Project> | |||||
| @@ -18,8 +18,11 @@ namespace Tensorflow | |||||
| { | { | ||||
| public static partial class tf | 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); | |||||
| /// <summary> | /// <summary> | ||||
| /// Returns a context manager that creates hierarchical names for operations. | /// Returns a context manager that creates hierarchical names for operations. | ||||
| @@ -28,8 +31,7 @@ namespace Tensorflow | |||||
| /// <param name="default_name">The default name to use if the name argument is None.</param> | /// <param name="default_name">The default name to use if the name argument is None.</param> | ||||
| /// <param name="values">The list of Tensor arguments that are passed to the op function.</param> | /// <param name="values">The list of Tensor arguments that are passed to the op function.</param> | ||||
| /// <returns>The scope name.</returns> | /// <returns>The scope name.</returns> | ||||
| 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); | |||||
| } | } | ||||
| } | } | ||||
| @@ -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(); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,8 +1,19 @@ | |||||
| namespace Tensorflow.Framework | namespace Tensorflow.Framework | ||||
| { | { | ||||
| public static class SparseTensor | |||||
| public interface _TensorLike | |||||
| { } | |||||
| public class SparseTensor : CompositeTensor, _TensorLike | |||||
| { | { | ||||
| private static Tensor _dense_shape { get; set; } | private static Tensor _dense_shape { get; set; } | ||||
| } | } | ||||
| public static class sparse_tensor | |||||
| { | |||||
| public static bool is_sparse(this _TensorLike x) | |||||
| { | |||||
| return x is SparseTensor; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -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); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -14,12 +14,15 @@ | |||||
| limitations under the License. | limitations under the License. | ||||
| ******************************************************************************/ | ******************************************************************************/ | ||||
| using System; | |||||
| using Tensorflow.Framework; | |||||
| namespace Tensorflow | namespace Tensorflow | ||||
| { | { | ||||
| /// <summary> | /// <summary> | ||||
| /// tensorflow\python\ops\resource_variable_ops.py | /// tensorflow\python\ops\resource_variable_ops.py | ||||
| /// </summary> | /// </summary> | ||||
| 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) | 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); | name: name); | ||||
| } | } | ||||
| /// <summary> | |||||
| /// | |||||
| /// </summary> | |||||
| /// <param name="self"></param> | |||||
| /// <param name="value"></param> | |||||
| /// <param name="use_locking"></param> | |||||
| /// <param name="read_value"></param> | |||||
| /// <returns> | |||||
| /// 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`. | |||||
| /// </returns> | |||||
| 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) | public static bool is_resource_variable(VariableV1 var) | ||||
| { | { | ||||
| return var is ResourceVariable; | return var is ResourceVariable; | ||||
| } | } | ||||
| /// <summary> | |||||
| /// Represents a future for a read of a variable. | |||||
| /// Pretends to be the tensor if anyone looks. | |||||
| /// </summary> | |||||
| public class _UnreadVariable : BaseResourceVariable | |||||
| { | |||||
| } | |||||
| /// <summary> | |||||
| /// A python variable from an existing handle. | |||||
| /// </summary> | |||||
| public class BaseResourceVariable : VariableV1 | |||||
| { | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -19,6 +19,7 @@ using System; | |||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Linq; | using System.Linq; | ||||
| using System.Runtime.InteropServices; | using System.Runtime.InteropServices; | ||||
| using Tensorflow.Framework; | |||||
| using static Tensorflow.Python; | using static Tensorflow.Python; | ||||
| namespace Tensorflow | namespace Tensorflow | ||||
| @@ -27,7 +28,7 @@ namespace Tensorflow | |||||
| /// A tensor is a generalization of vectors and matrices to potentially higher dimensions. | /// A tensor is a generalization of vectors and matrices to potentially higher dimensions. | ||||
| /// Internally, TensorFlow represents tensors as n-dimensional arrays of base datatypes. | /// Internally, TensorFlow represents tensors as n-dimensional arrays of base datatypes. | ||||
| /// </summary> | /// </summary> | ||||
| public partial class Tensor : IDisposable, ITensorOrOperation | |||||
| public partial class Tensor : IDisposable, ITensorOrOperation, _TensorLike | |||||
| { | { | ||||
| private IntPtr _handle; | private IntPtr _handle; | ||||
| @@ -109,6 +110,8 @@ namespace Tensorflow | |||||
| this.shape = shape.Dimensions; | this.shape = shape.Dimensions; | ||||
| } | } | ||||
| public int[] dims => shape; | |||||
| /// <summary> | /// <summary> | ||||
| /// number of dimensions | /// number of dimensions | ||||
| /// 0 Scalar (magnitude only) | /// 0 Scalar (magnitude only) | ||||
| @@ -205,5 +205,10 @@ namespace Tensorflow | |||||
| { | { | ||||
| return (int)type > 100; | 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(); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -214,6 +214,12 @@ namespace Tensorflow | |||||
| else | else | ||||
| nparray = Convert.ToString(values); | nparray = Convert.ToString(values); | ||||
| break; | break; | ||||
| case "Boolean": | |||||
| if (values.GetType().IsArray) | |||||
| nparray = np.array((bool[])values, np_dt); | |||||
| else | |||||
| nparray = Convert.ToBoolean(values); | |||||
| break; | |||||
| default: | default: | ||||
| throw new NotImplementedException($"make_tensor_proto: Support for type {np_dt.Name} Not Implemented"); | throw new NotImplementedException($"make_tensor_proto: Support for type {np_dt.Name} Not Implemented"); | ||||
| } | } | ||||
| @@ -40,6 +40,8 @@ namespace Tensorflow | |||||
| public override string name => _variable.name; | public override string name => _variable.name; | ||||
| public Tensor eval() => _variable; | |||||
| public RefVariable(object initial_value = null, | public RefVariable(object initial_value = null, | ||||
| bool trainable = true, | bool trainable = true, | ||||
| List<string> collections = null, | List<string> collections = null, | ||||
| @@ -12,102 +12,102 @@ | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | See the License for the specific language governing permissions and | ||||
| limitations under the License. | 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(); | |||||
| /// <summary> | |||||
| /// 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. | |||||
| /// </summary> | |||||
| /// <param name="shape">The shape of the variable tensor.</param> | |||||
| /// <param name="dtype">The type of elements in the variable tensor.</param> | |||||
| /// <param name="name"></param> | |||||
| /// <param name="container"></param> | |||||
| /// <param name="shared_name"></param> | |||||
| /// <returns></returns> | |||||
| 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<string, object>(); | |||||
| _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]; | |||||
| } | |||||
| /// <summary> | |||||
| /// Update 'ref' by assigning 'value' to it | |||||
| /// </summary> | |||||
| /// <param name="REF"></param> | |||||
| /// <param name="value"></param> | |||||
| /// <param name="validate_shape"></param> | |||||
| /// <param name="use_locking"></param> | |||||
| /// <param name="name"></param> | |||||
| 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<string, object>(); | |||||
| _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(); | |||||
| /// <summary> | |||||
| /// 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. | |||||
| /// </summary> | |||||
| /// <param name="shape">The shape of the variable tensor.</param> | |||||
| /// <param name="dtype">The type of elements in the variable tensor.</param> | |||||
| /// <param name="name"></param> | |||||
| /// <param name="container"></param> | |||||
| /// <param name="shared_name"></param> | |||||
| /// <returns></returns> | |||||
| 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<string, object>(); | |||||
| _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]; | |||||
| } | |||||
| /// <summary> | |||||
| /// Update 'ref' by assigning 'value' to it | |||||
| /// </summary> | |||||
| /// <param name="REF"></param> | |||||
| /// <param name="value"></param> | |||||
| /// <param name="validate_shape"></param> | |||||
| /// <param name="use_locking"></param> | |||||
| /// <param name="name"></param> | |||||
| 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<string, object>(); | |||||
| _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, | public static Tensor assign(RefVariable @ref, object value, | ||||
| bool validate_shape = true, | 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<string, object>(); | |||||
| _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<string, object>(); | |||||
| _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). | // name: A name for the operation(optional). | ||||
| // Returns: | // Returns: | ||||
| // A mutable `Tensor`. Has the same type as `ref`. | // 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]; | |||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| @@ -142,8 +142,8 @@ namespace Tensorflow | |||||
| /// <returns></returns> | /// <returns></returns> | ||||
| public static Tensor scatter_add(RefVariable @ref, Tensor indices, Tensor updates, bool use_locking = false, string name = null) | 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]; | return _op.outputs[0]; | ||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -12,99 +12,99 @@ | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | See the License for the specific language governing permissions and | ||||
| limitations under the License. | limitations under the License. | ||||
| ******************************************************************************/ | |||||
| using System; | |||||
| namespace Tensorflow | |||||
| { | |||||
| public class state_ops | |||||
| { | |||||
| /// <summary> | |||||
| /// Create a variable Operation. | |||||
| /// </summary> | |||||
| /// <param name="shape"></param> | |||||
| /// <param name="dtype"></param> | |||||
| /// <param name="name"></param> | |||||
| /// <param name="container"></param> | |||||
| /// <param name="shared_name"></param> | |||||
| /// <returns></returns> | |||||
| 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 | |||||
| { | |||||
| /// <summary> | |||||
| /// Create a variable Operation. | |||||
| /// </summary> | |||||
| /// <param name="shape"></param> | |||||
| /// <param name="dtype"></param> | |||||
| /// <param name="name"></param> | |||||
| /// <param name="container"></param> | |||||
| /// <param name="shared_name"></param> | |||||
| /// <returns></returns> | |||||
| 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, | return gen_state_ops.assign(@ref, | ||||
| value, | value, | ||||
| validate_shape: validate_shape, | validate_shape: validate_shape, | ||||
| use_locking: use_locking, | 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: | // Returns: | ||||
| // Same as "ref". Returned as a convenience for operations that want | // Same as "ref". Returned as a convenience for operations that want | ||||
| // to use the new value after the variable has been updated. | // 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) | public static Tensor scatter_add(RefVariable @ref, Tensor indices, Tensor updates, bool use_locking = false, string name = null) | ||||
| { | { | ||||
| if (@ref.dtype.is_ref_dtype()) | if (@ref.dtype.is_ref_dtype()) | ||||
| return gen_state_ops.scatter_add(@ref, indices, updates, use_locking: use_locking, name: name); | return gen_state_ops.scatter_add(@ref, indices, updates, use_locking: use_locking, name: name); | ||||
| throw new NotImplementedException("scatter_add"); | throw new NotImplementedException("scatter_add"); | ||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -46,7 +46,7 @@ namespace Tensorflow | |||||
| trainable: trainable, | trainable: trainable, | ||||
| validate_shape: validate_shape, | validate_shape: validate_shape, | ||||
| name: name, | name: name, | ||||
| dtype: TF_DataType.DtInvalid); | |||||
| dtype: dtype); | |||||
| } | } | ||||
| public static unsafe Tensor placeholder(TF_DataType dtype, TensorShape shape = null, string name = null) | public static unsafe Tensor placeholder(TF_DataType dtype, TensorShape shape = null, string name = null) | ||||
| @@ -2,6 +2,19 @@ | |||||
| <PropertyGroup> | <PropertyGroup> | ||||
| <TargetFramework>netcoreapp2.2</TargetFramework> | <TargetFramework>netcoreapp2.2</TargetFramework> | ||||
| <GeneratePackageOnBuild>true</GeneratePackageOnBuild> | |||||
| <PackageId>SciSharp.TensorFlowText</PackageId> | |||||
| <Version>0.0.1</Version> | |||||
| <Authors>Haiping Chen</Authors> | |||||
| <Company>SciSharp STACK</Company> | |||||
| <Product>TensorFlowText</Product> | |||||
| <Description>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.</Description> | |||||
| <Copyright>Apache 2.0</Copyright> | |||||
| <PackageProjectUrl>http://scisharpstack.org</PackageProjectUrl> | |||||
| <RepositoryUrl>https://github.com/SciSharp/TensorFlow.NET</RepositoryUrl> | |||||
| <PackageTags>TensorFlow, SciSharp</PackageTags> | |||||
| <RepositoryType>git</RepositoryType> | |||||
| <PackageIconUrl>https://avatars3.githubusercontent.com/u/44989469?s=200&v=4</PackageIconUrl> | |||||
| </PropertyGroup> | </PropertyGroup> | ||||
| </Project> | </Project> | ||||
| @@ -735,21 +735,43 @@ namespace TensorFlowNET.Examples.ImageProcess | |||||
| var labels = File.ReadAllLines(output_labels); | 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, ""); | 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 => | 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 prob = np.squeeze(result); | ||||
| var idx = np.argmax(prob); | 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)); | |||||
| }); | }); | ||||
| } | } | ||||