| @@ -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; | |||
| } | |||
| } | |||
| @@ -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); | |||
| @@ -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; } | |||
| @@ -2,8 +2,21 @@ | |||
| <PropertyGroup> | |||
| <RootNamespace>Tensorflow.Hub</RootNamespace> | |||
| <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> | |||
| <ItemGroup> | |||
| <ProjectReference Include="..\..\src\TensorFlowNET.Core\TensorFlowNET.Core.csproj" /> | |||
| <PackageReference Include="NumSharp" Version="0.10.6" /> | |||
| </ItemGroup> | |||
| </Project> | |||
| </Project> | |||
| @@ -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); | |||
| /// <summary> | |||
| /// 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="values">The list of Tensor arguments that are passed to the op function.</param> | |||
| /// <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 | |||
| { | |||
| 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; | |||
| } | |||
| } | |||
| } | |||
| @@ -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. | |||
| ******************************************************************************/ | |||
| using System; | |||
| using Tensorflow.Framework; | |||
| namespace Tensorflow | |||
| { | |||
| /// <summary> | |||
| /// tensorflow\python\ops\resource_variable_ops.py | |||
| /// </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) | |||
| { | |||
| @@ -29,9 +32,61 @@ namespace Tensorflow | |||
| 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) | |||
| { | |||
| 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.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. | |||
| /// </summary> | |||
| 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; | |||
| /// <summary> | |||
| /// number of dimensions | |||
| /// 0 Scalar (magnitude only) | |||
| @@ -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(); | |||
| } | |||
| } | |||
| } | |||
| @@ -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"); | |||
| } | |||
| @@ -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<string> collections = null, | |||
| @@ -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(); | |||
| /// <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, | |||
| 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). | |||
| // 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]; | |||
| } | |||
| /// <summary> | |||
| @@ -142,8 +142,8 @@ namespace Tensorflow | |||
| /// <returns></returns> | |||
| 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]; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -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 | |||
| { | |||
| /// <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, | |||
| 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"); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -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) | |||
| @@ -2,6 +2,19 @@ | |||
| <PropertyGroup> | |||
| <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> | |||
| </Project> | |||
| @@ -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)); | |||
| }); | |||
| } | |||