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


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

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


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

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


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

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


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

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

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

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


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

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

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

+ 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
{
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;


+ 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]
public class OperationsTest
{
[TestMethod]
public void constant()
{
var x = tf.constant(4.0f);
}

[TestMethod]
public void placeholder()
{


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

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


Loading…
Cancel
Save