Esther2013 6 years ago
parent
commit
c448f029e8
18 changed files with 414 additions and 209 deletions
  1. +3
    -3
      src/TensorFlowHub/MnistDataSet.cs
  2. +3
    -3
      src/TensorFlowHub/MnistModelLoader.cs
  3. +1
    -1
      src/TensorFlowHub/ModelLoadSetting.cs
  4. +15
    -2
      src/TensorFlowHub/TensorFlowHub.csproj
  5. +7
    -5
      src/TensorFlowNET.Core/APIs/tf.ops.cs
  6. +39
    -0
      src/TensorFlowNET.Core/Contrib/Learn/Estimators/tensor_signature.cs
  7. +12
    -1
      src/TensorFlowNET.Core/Framework/sparse_tensor.py.cs
  8. +34
    -0
      src/TensorFlowNET.Core/Framework/tensor_shape.cs
  9. +56
    -1
      src/TensorFlowNET.Core/Operations/resource_variable_ops.cs
  10. +4
    -1
      src/TensorFlowNET.Core/Tensors/Tensor.cs
  11. +5
    -0
      src/TensorFlowNET.Core/Tensors/dtypes.cs
  12. +6
    -0
      src/TensorFlowNET.Core/Tensors/tensor_util.cs
  13. +2
    -0
      src/TensorFlowNET.Core/Variables/RefVariable.cs
  14. +102
    -102
      src/TensorFlowNET.Core/Variables/gen_state_ops.py.cs
  15. +81
    -81
      src/TensorFlowNET.Core/Variables/state_ops.cs
  16. +1
    -1
      src/TensorFlowNET.Core/tf.cs
  17. +13
    -0
      src/TensorFlowText/TensorFlowText.csproj
  18. +30
    -8
      test/TensorFlowNET.Examples/ImageProcessing/RetrainImageClassifier.cs

+ 3
- 3
src/TensorFlowHub/MnistDataSet.cs View File

@@ -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;
} }
} }


+ 3
- 3
src/TensorFlowHub/MnistModelLoader.cs View File

@@ -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);


+ 1
- 1
src/TensorFlowHub/ModelLoadSetting.cs View File

@@ -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; }


+ 15
- 2
src/TensorFlowHub/TensorFlowHub.csproj View File

@@ -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&amp;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>

+ 7
- 5
src/TensorFlowNET.Core/APIs/tf.ops.cs View File

@@ -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);
} }
} }

+ 39
- 0
src/TensorFlowNET.Core/Contrib/Learn/Estimators/tensor_signature.cs View File

@@ -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();
}
}
}

+ 12
- 1
src/TensorFlowNET.Core/Framework/sparse_tensor.py.cs View File

@@ -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;
}
}
} }

+ 34
- 0
src/TensorFlowNET.Core/Framework/tensor_shape.cs View File

@@ -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);
}
}
}

+ 56
- 1
src/TensorFlowNET.Core/Operations/resource_variable_ops.cs View File

@@ -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
{
}
} }
} }

+ 4
- 1
src/TensorFlowNET.Core/Tensors/Tensor.cs View File

@@ -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)


+ 5
- 0
src/TensorFlowNET.Core/Tensors/dtypes.cs View File

@@ -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();
}
} }
} }

+ 6
- 0
src/TensorFlowNET.Core/Tensors/tensor_util.cs View File

@@ -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");
} }


+ 2
- 0
src/TensorFlowNET.Core/Variables/RefVariable.cs View File

@@ -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,


+ 102
- 102
src/TensorFlowNET.Core/Variables/gen_state_ops.py.cs View File

@@ -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];
}
}
}
}
}
}

+ 81
- 81
src/TensorFlowNET.Core/Variables/state_ops.cs View File

@@ -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");
}
}
}
}
}
}

+ 1
- 1
src/TensorFlowNET.Core/tf.cs View File

@@ -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)


+ 13
- 0
src/TensorFlowText/TensorFlowText.csproj View File

@@ -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&amp;v=4</PackageIconUrl>
</PropertyGroup> </PropertyGroup>


</Project> </Project>

+ 30
- 8
test/TensorFlowNET.Examples/ImageProcessing/RetrainImageClassifier.cs View File

@@ -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));
}); });
} }




Loading…
Cancel
Save