| @@ -39,7 +39,7 @@ namespace Tensorflow | |||
| _outputs = new Tensor[num_outputs]; | |||
| 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); | |||
| @@ -25,7 +25,7 @@ namespace Tensorflow | |||
| private static OpDefLibrary _InitOpDefLibrary() | |||
| { | |||
| // 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_def_lib = new OpDefLibrary(); | |||
| op_def_lib.add_op_list(op_list); | |||
| @@ -16,18 +16,16 @@ namespace Tensorflow | |||
| 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) | |||
| { | |||
| var op_desc = c_api.TF_NewOperation(graph.Handle, node_def.Op, node_def.Name); | |||
| @@ -27,10 +27,10 @@ | |||
| <None Update="tensorflow.dll"> | |||
| <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | |||
| </None> | |||
| <None Update="Protobuf\op_list_proto_array.bin"> | |||
| <None Update="Operations\op_list_proto_array.bin"> | |||
| <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | |||
| </None> | |||
| <None Update="Protobuf\op_list_proto_math.bin"> | |||
| <None Update="Operations\op_list_proto_math.bin"> | |||
| <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | |||
| </None> | |||
| </ItemGroup> | |||
| @@ -7,6 +7,7 @@ namespace Tensorflow | |||
| public class RefVariable : Variable | |||
| { | |||
| public bool _in_graph_mode = true; | |||
| public Tensor _initial_value; | |||
| public RefVariable(object initial_value, | |||
| 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"); | |||
| } | |||
| } | |||
| } | |||
| @@ -13,12 +13,12 @@ namespace Tensorflow | |||
| /// </summary> | |||
| public class Tensor | |||
| { | |||
| public Operation op { get; } | |||
| public int value_index { get; } | |||
| public Graph graph => op.graph; | |||
| public Operation op { get; } | |||
| public string name; | |||
| public object value; | |||
| public int value_index { get; } | |||
| public TF_DataType dtype { get; } | |||
| public IntPtr handle { get; } | |||
| @@ -6,23 +6,14 @@ using System.Text; | |||
| namespace Tensorflow | |||
| { | |||
| /// <summary> | |||
| /// Represents the shape of a `Tensor`. | |||
| /// </summary> | |||
| 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); | |||
| } | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| } | |||
| @@ -8,44 +8,84 @@ namespace Tensorflow | |||
| { | |||
| 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; | |||
| TensorProto tensor_proto = null; | |||
| TensorShape tensor_shape = new TensorShape(0); | |||
| TF_DataType numpy_dtype; | |||
| if(shape is null) | |||
| { | |||
| shape = new Shape(); | |||
| } | |||
| 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: | |||
| 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 | |||
| { | |||
| 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); | |||
| break; | |||
| 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 | |||
| { | |||
| 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); | |||
| break; | |||
| 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 | |||
| { | |||
| 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)); | |||
| break; | |||
| default: | |||
| throw new Exception("Not Implemented"); | |||
| } | |||
| 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; | |||
| } | |||
| } | |||
| } | |||
| @@ -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); | |||
| } | |||
| } | |||
| } | |||
| @@ -8,7 +8,7 @@ using Tensorflow.Eager; | |||
| namespace Tensorflow | |||
| { | |||
| public static class tf | |||
| public static partial class tf | |||
| { | |||
| public static TF_DataType float32 = TF_DataType.TF_FLOAT; | |||
| public static TF_DataType chars = TF_DataType.TF_STRING; | |||
| @@ -32,25 +32,6 @@ namespace Tensorflow | |||
| 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() | |||
| { | |||
| context.default_execution_mode = Context.EAGER_MODE; | |||
| @@ -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"); | |||
| } | |||
| } | |||
| } | |||
| @@ -9,12 +9,6 @@ namespace TensorFlowNET.UnitTest | |||
| [TestClass] | |||
| public class OperationsTest | |||
| { | |||
| [TestMethod] | |||
| public void constant() | |||
| { | |||
| var x = tf.constant(4.0f); | |||
| } | |||
| [TestMethod] | |||
| public void placeholder() | |||
| { | |||
| @@ -9,6 +9,7 @@ namespace TensorFlowNET.UnitTest | |||
| [TestClass] | |||
| public class VariableTest | |||
| { | |||
| [TestMethod] | |||
| public void Creating() | |||
| { | |||
| var mammal = tf.Variable("Elephant", tf.chars); | |||