Browse Source

Scalar and String constant creation.

tags/v0.1.0-Tensor
Oceania2018 7 years ago
parent
commit
1d2fe5b2c6
17 changed files with 214 additions and 65 deletions
  1. +1
    -1
      src/TensorFlowNET.Core/Operations/Operation.cs
  2. +1
    -1
      src/TensorFlowNET.Core/Operations/gen_math_ops.cs
  3. +0
    -0
      src/TensorFlowNET.Core/Operations/op_list_proto_array.bin
  4. +0
    -0
      src/TensorFlowNET.Core/Operations/op_list_proto_math.bin
  5. +4
    -6
      src/TensorFlowNET.Core/Operations/ops.cs
  6. +2
    -2
      src/TensorFlowNET.Core/TensorFlowNET.Core.csproj
  7. +4
    -2
      src/TensorFlowNET.Core/Tensors/RefVariable.cs
  8. +3
    -3
      src/TensorFlowNET.Core/Tensors/Tensor.cs
  9. +4
    -13
      src/TensorFlowNET.Core/Tensors/TensorShape.cs
  10. +41
    -0
      src/TensorFlowNET.Core/Tensors/constant_op.cs
  11. +59
    -0
      src/TensorFlowNET.Core/Tensors/dtypes.cs
  12. +51
    -11
      src/TensorFlowNET.Core/Tensors/tensor_util.cs
  13. +14
    -0
      src/TensorFlowNET.Core/Tensors/tf.constant.cs
  14. +1
    -20
      src/TensorFlowNET.Core/tf.cs
  15. +28
    -0
      test/TensorFlowNET.UnitTest/ConstantTest.cs
  16. +0
    -6
      test/TensorFlowNET.UnitTest/OperationsTest.cs
  17. +1
    -0
      test/TensorFlowNET.UnitTest/VariableTest.cs

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

@@ -39,7 +39,7 @@ namespace Tensorflow
_outputs = new Tensor[num_outputs]; _outputs = new Tensor[num_outputs];
for (int i = 0; i < num_outputs; i++) for (int i = 0; i < num_outputs; i++)
{ {
_outputs[i] = new Tensor(this, i, TF_DataType.TF_FLOAT);
_outputs[i] = new Tensor(this, i, output_types[i]);
} }


_graph._add_op(this); _graph._add_op(this);


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

@@ -25,7 +25,7 @@ namespace Tensorflow
private static OpDefLibrary _InitOpDefLibrary() private static OpDefLibrary _InitOpDefLibrary()
{ {
// c_api.TF_GraphGetOpDef(g.Handle, op_type_name, buffer.Handle, status.Handle); // c_api.TF_GraphGetOpDef(g.Handle, op_type_name, buffer.Handle, status.Handle);
var bytes = File.ReadAllBytes("Tensorflow/op_list_proto_math.bin");
var bytes = File.ReadAllBytes("Operations/op_list_proto_math.bin");
var op_list = OpList.Parser.ParseFrom(bytes); var op_list = OpList.Parser.ParseFrom(bytes);
var op_def_lib = new OpDefLibrary(); var op_def_lib = new OpDefLibrary();
op_def_lib.add_op_list(op_list); op_def_lib.add_op_list(op_list);


src/TensorFlowNET.Core/Protobuf/op_list_proto_array.bin → src/TensorFlowNET.Core/Operations/op_list_proto_array.bin View File


src/TensorFlowNET.Core/Protobuf/op_list_proto_math.bin → src/TensorFlowNET.Core/Operations/op_list_proto_math.bin View File


+ 4
- 6
src/TensorFlowNET.Core/Operations/ops.cs View File

@@ -16,18 +16,16 @@ namespace Tensorflow
return tf.Graph(); return tf.Graph();
} }


public static Tensor convert_to_tensor()
public static Tensor convert_to_tensor(object value, string name = "")
{ {
return internal_convert_to_tensor();
return internal_convert_to_tensor(value, name);
} }


private static Tensor internal_convert_to_tensor()
private static Tensor internal_convert_to_tensor(object value, string name = "")
{ {
return null;
return tf.constant(value);
} }




public static unsafe IntPtr _create_c_op(Graph graph, NodeDef node_def, List<Tensor> inputs) public static unsafe IntPtr _create_c_op(Graph graph, NodeDef node_def, List<Tensor> inputs)
{ {
var op_desc = c_api.TF_NewOperation(graph.Handle, node_def.Op, node_def.Name); var op_desc = c_api.TF_NewOperation(graph.Handle, node_def.Op, node_def.Name);


+ 2
- 2
src/TensorFlowNET.Core/TensorFlowNET.Core.csproj View File

@@ -27,10 +27,10 @@
<None Update="tensorflow.dll"> <None Update="tensorflow.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Update="Protobuf\op_list_proto_array.bin">
<None Update="Operations\op_list_proto_array.bin">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Update="Protobuf\op_list_proto_math.bin">
<None Update="Operations\op_list_proto_math.bin">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
</ItemGroup> </ItemGroup>


+ 4
- 2
src/TensorFlowNET.Core/Tensors/RefVariable.cs View File

@@ -7,6 +7,7 @@ namespace Tensorflow
public class RefVariable : Variable public class RefVariable : Variable
{ {
public bool _in_graph_mode = true; public bool _in_graph_mode = true;
public Tensor _initial_value;


public RefVariable(object initial_value, public RefVariable(object initial_value,
TF_DataType trainable, TF_DataType trainable,
@@ -16,9 +17,10 @@ namespace Tensorflow


} }


private void _init_from_args()
private void _init_from_args(object initial_value,
TF_DataType trainable)
{ {
_initial_value = ops.convert_to_tensor(initial_value, name: "initial_value");
} }
} }
} }

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

@@ -13,12 +13,12 @@ namespace Tensorflow
/// </summary> /// </summary>
public class Tensor public class Tensor
{ {
public Operation op { get; }
public int value_index { get; }

public Graph graph => op.graph; public Graph graph => op.graph;
public Operation op { get; }


public string name; public string name;
public object value;
public int value_index { get; }


public TF_DataType dtype { get; } public TF_DataType dtype { get; }
public IntPtr handle { get; } public IntPtr handle { get; }


+ 4
- 13
src/TensorFlowNET.Core/Tensors/TensorShape.cs View File

@@ -6,23 +6,14 @@ using System.Text;


namespace Tensorflow namespace Tensorflow
{ {
/// <summary>
/// Represents the shape of a `Tensor`.
/// </summary>
public class TensorShape : Shape public class TensorShape : Shape
{ {
public TensorShape(params int[] shape) : base(shape)
public TensorShape(params int[] dims) : base(dims)
{ {


} }

public TensorShape as_shape()
{
return this;
}

public TensorShapeProto as_proto()
{
TensorShapeProto dim = new TensorShapeProto();

return new TensorShapeProto(dim);
}
} }
} }

+ 41
- 0
src/TensorFlowNET.Core/Tensors/constant_op.cs View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Tensorflow
{
public class constant_op
{
/// <summary>
/// Creates a constant tensor.
///
/// The resulting tensor is populated with values of type `dtype`, as
/// specified by arguments `value` and (optionally) `shape`
/// </summary>
/// <param name="value">A constant value (or list) of output type `dtype`.</param>
/// <param name="dtype">The type of the elements of the resulting tensor.</param>
/// <param name="shape">Optional dimensions of resulting tensor.</param>
/// <param name="name">Optional name for the tensor.</param>
/// <param name="verify_shape">Boolean that enables verification of a shape of values.</param>
/// <returns></returns>
public static Tensor Create(object value, TF_DataType dtype = TF_DataType.DtInvalid, TensorShape shape = null, string name = "Const", bool verify_shape = false)
{
Graph g = ops.get_default_graph();
var tensor_value = new AttrValue();
var tensor_pb = tensor_util.make_tensor_proto(value, dtype, shape, verify_shape);
tensor_value.Tensor = tensor_pb;
var dtype_value = new AttrValue
{
Type = tensor_value.Tensor.Dtype,
};

var attrs = new Dictionary<string, AttrValue>();
attrs["dtype"] = dtype_value;
attrs["value"] = tensor_value;
var const_tensor = g.create_op("Const", null, new TF_DataType[] { (TF_DataType)dtype_value.Type }, attrs: attrs).outputs[0];
const_tensor.value = value;

return const_tensor;
}
}
}

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

@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Tensorflow
{
public static class dtypes
{
public static TF_DataType as_dtype(Type type)
{
TF_DataType dtype = TF_DataType.DtInvalid;

switch (type.Name)
{
case "Int32":
dtype = TF_DataType.TF_INT32;
break;
case "Single":
dtype = TF_DataType.TF_FLOAT;
break;
case "Double":
dtype = TF_DataType.TF_DOUBLE;
break;
case "String":
dtype = TF_DataType.TF_STRING;
break;
default:
throw new Exception("Not Implemented");
}

return dtype;
}

public static DataType as_datatype_enum(this TF_DataType type)
{
DataType dtype = DataType.DtInvalid;

switch (type)
{
case TF_DataType.TF_INT32:
dtype = DataType.DtInt32;
break;
case TF_DataType.TF_FLOAT:
dtype = DataType.DtFloat;
break;
case TF_DataType.TF_DOUBLE:
dtype = DataType.DtDouble;
break;
case TF_DataType.TF_STRING:
dtype = DataType.DtString;
break;
default:
throw new Exception("Not Implemented");
}

return dtype;
}
}
}

+ 51
- 11
src/TensorFlowNET.Core/Tensors/tensor_util.cs View File

@@ -8,44 +8,84 @@ namespace Tensorflow
{ {
public static class tensor_util public static class tensor_util
{ {
public static TensorProto make_tensor_proto(object values, Type dtype = null)
public static TensorProto make_tensor_proto(object values, TF_DataType dtype = TF_DataType.DtInvalid, Shape shape = null, bool verify_shape = false)
{ {
NDArray nparray; NDArray nparray;
TensorProto tensor_proto = null; TensorProto tensor_proto = null;
TensorShape tensor_shape = new TensorShape(0);
TF_DataType numpy_dtype;
if(shape is null)
{
shape = new Shape();
}


switch (values) switch (values)
{ {
case int val:
nparray = np.asarray(val);
numpy_dtype = dtypes.as_dtype(nparray.dtype);
tensor_proto = new tensor_pb2.TensorProto
{
Dtype = numpy_dtype.as_datatype_enum(),
TensorShape = shape.as_shape(nparray.shape).as_proto()
};
tensor_proto.IntVal.Add(val);
break;
case float val: case float val:
nparray = np.array(new float[] { val }, np.float32);
nparray = np.asarray(val);
numpy_dtype = dtypes.as_dtype(nparray.dtype);
tensor_proto = new tensor_pb2.TensorProto tensor_proto = new tensor_pb2.TensorProto
{ {
Dtype = DataType.DtFloat,
TensorShape = tensor_shape.as_shape().as_proto()
Dtype = numpy_dtype.as_datatype_enum(),
TensorShape = shape.as_shape(nparray.shape).as_proto()
}; };
tensor_proto.FloatVal.Add(val); tensor_proto.FloatVal.Add(val);
break; break;
case double val: case double val:
nparray = np.array(new double[] { val }, np.float64);
nparray = np.asarray(val);
numpy_dtype = dtypes.as_dtype(nparray.dtype);
tensor_proto = new tensor_pb2.TensorProto tensor_proto = new tensor_pb2.TensorProto
{ {
Dtype = DataType.DtDouble,
TensorShape = tensor_shape.as_shape().as_proto()
Dtype = numpy_dtype.as_datatype_enum(),
TensorShape = shape.as_shape(nparray.shape).as_proto()
}; };
tensor_proto.DoubleVal.Add(val); tensor_proto.DoubleVal.Add(val);
break; break;
case string val: case string val:
nparray = np.array(new string[] { val }, np.chars);
nparray = np.asarray(val);
numpy_dtype = dtypes.as_dtype(nparray.dtype);
tensor_proto = new tensor_pb2.TensorProto tensor_proto = new tensor_pb2.TensorProto
{ {
Dtype = DataType.DtString,
TensorShape = tensor_shape.as_shape().as_proto()
Dtype = numpy_dtype.as_datatype_enum(),
TensorShape = shape.as_shape(nparray.shape).as_proto()
}; };
tensor_proto.StringVal.Add(Google.Protobuf.ByteString.CopyFrom(val, Encoding.UTF8)); tensor_proto.StringVal.Add(Google.Protobuf.ByteString.CopyFrom(val, Encoding.UTF8));
break; break;
default:
throw new Exception("Not Implemented");
} }


return tensor_proto; return tensor_proto;
} }

public static TensorShape as_shape(this Shape shape, int[] dims)
{
return new TensorShape(dims);
}

public static TensorShapeProto as_proto(this TensorShape tshape)
{
TensorShapeProto shape = new TensorShapeProto();

for (int i = 0; i < tshape.NDim; i++)
{
var dim = new TensorShapeProto.Types.Dim();
dim.Size = tshape.Dimensions[i];
dim.Name = $"{dim}_1";

shape.Dim.Add(dim);
}

return shape;
}
} }
} }

+ 14
- 0
src/TensorFlowNET.Core/Tensors/tf.constant.cs View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Tensorflow
{
public static partial class tf
{
public static Tensor constant(object value, TF_DataType dtype = TF_DataType.DtInvalid, TensorShape shape = null, string name = "Const", bool verify_shape = false)
{
return constant_op.Create(value, dtype, shape, name, verify_shape);
}
}
}

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

@@ -8,7 +8,7 @@ using Tensorflow.Eager;


namespace Tensorflow namespace Tensorflow
{ {
public static class tf
public static partial class tf
{ {
public static TF_DataType float32 = TF_DataType.TF_FLOAT; public static TF_DataType float32 = TF_DataType.TF_FLOAT;
public static TF_DataType chars = TF_DataType.TF_STRING; public static TF_DataType chars = TF_DataType.TF_STRING;
@@ -32,25 +32,6 @@ namespace Tensorflow
return gen_array_ops.placeholder(dtype, shape); return gen_array_ops.placeholder(dtype, shape);
} }


public static unsafe Tensor constant(object value)
{
var g = ops.get_default_graph();
var tensor_value = new attr_value_pb2.AttrValue();
var tensor_pb = tensor_util.make_tensor_proto(value);
tensor_value.Tensor = tensor_pb;
var dtype_value = new attr_value_pb2.AttrValue
{
Type = tensor_value.Tensor.Dtype,
};

var attrs = new Dictionary<string, AttrValue>();
attrs["dtype"] = dtype_value;
attrs["value"] = tensor_value;
var const_tensor = g.create_op("Const", null, new TF_DataType[] { (TF_DataType)dtype_value.Type }, attrs: attrs).outputs[0];

return const_tensor;
}

public static void enable_eager_execution() public static void enable_eager_execution()
{ {
context.default_execution_mode = Context.EAGER_MODE; context.default_execution_mode = Context.EAGER_MODE;


+ 28
- 0
test/TensorFlowNET.UnitTest/ConstantTest.cs View File

@@ -0,0 +1,28 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Text;
using Tensorflow;

namespace TensorFlowNET.UnitTest
{
[TestClass]
public class ConstantTest
{
Tensor tensor;

[TestMethod]
public void ScalarConst()
{
tensor = tf.constant(8); // int
tensor = tf.constant(6.0f); // float
tensor = tf.constant(6.0); // double
}

[TestMethod]
public void StringConst()
{
tensor = tf.constant("Elephant");
}
}
}

+ 0
- 6
test/TensorFlowNET.UnitTest/OperationsTest.cs View File

@@ -9,12 +9,6 @@ namespace TensorFlowNET.UnitTest
[TestClass] [TestClass]
public class OperationsTest public class OperationsTest
{ {
[TestMethod]
public void constant()
{
var x = tf.constant(4.0f);
}

[TestMethod] [TestMethod]
public void placeholder() public void placeholder()
{ {


+ 1
- 0
test/TensorFlowNET.UnitTest/VariableTest.cs View File

@@ -9,6 +9,7 @@ namespace TensorFlowNET.UnitTest
[TestClass] [TestClass]
public class VariableTest public class VariableTest
{ {
[TestMethod]
public void Creating() public void Creating()
{ {
var mammal = tf.Variable("Elephant", tf.chars); var mammal = tf.Variable("Elephant", tf.chars);


Loading…
Cancel
Save