diff --git a/README.md b/README.md index 2cd2060b..fdfc6de7 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ TensorFlow.NET provides .NET Standard binding for [TensorFlow](https://www.tensorflow.org/). [![Join the chat at https://gitter.im/publiclab/publiclab](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Tensorflow-NET) +![Tensorflow.NET](https://ci.appveyor.com/api/projects/status/tensorflow-net-p7kmsjyo10ey?svg=true) TensorFlow.NET is a member project of SciSharp stack. @@ -10,11 +11,12 @@ TensorFlow.NET is a member project of SciSharp stack. ### How to use Download the pre-compiled dll [here](tensorflowlib) and place it in the bin folder. +Import tensorflow.net. ```cs -// import tensorflow.net -using using Tensorflow; +using Tensorflow; ``` +Add two constants. ```cs // Create a Constant op var a = tf.constant(4.0f); @@ -27,6 +29,7 @@ using (var sess = tf.Session()) } ``` +Feed placeholder. ```cs // Create a placeholder op var a = tf.placeholder(tf.float32); diff --git a/The Definitive Guide to Tensorflow.NET/CH_1 Tensor.md b/The Definitive Guide to Tensorflow.NET/CH_1 Tensor.md index 17753b29..b499c6ec 100644 --- a/The Definitive Guide to Tensorflow.NET/CH_1 Tensor.md +++ b/The Definitive Guide to Tensorflow.NET/CH_1 Tensor.md @@ -4,3 +4,28 @@ ### 表示一个操作的输出 + + +##### What is Tensor? + +##### Tensor 是什么? + + + + + +TF uses column major order. + +TF 采用的是按列存储模式,如果我们用NumSharp产生一个2 X 3的矩阵,如果按顺序从0到5访问数据的话,是不会得到1-6的数字的,而是得到1,4, 2, 5, 3, 6这个顺序的一组数字。 + +```cs +// generate a matrix:[[1, 2, 3], [4, 5, 6]] +var nd = np.array(1f, 2f, 3f, 4f, 5f, 6f).reshape(2, 3); +// the index will be 0 2 4 1 3 5, it's column-major order. +``` + + + +![1545631998951](assets/column-major order.png) + +![1545631998951](assets/row-major order.png) diff --git a/The Definitive Guide to Tensorflow.NET/INTRO.md b/The Definitive Guide to Tensorflow.NET/INTRO.md index c80c7333..79be7c83 100644 --- a/The Definitive Guide to Tensorflow.NET/INTRO.md +++ b/The Definitive Guide to Tensorflow.NET/INTRO.md @@ -22,4 +22,12 @@ TensorFlow is an open source project for machine learning especially for deep le -为了避免混淆,本书中对TensorFlow中定义的特有类不进行翻译,比如Tensor, Graph, Shape这些词都会保留英文名称。 \ No newline at end of file +为了避免混淆,本书中对TensorFlow中定义的特有类不进行翻译,比如Tensor, Graph, Shape这些词都会保留英文名称。 + + + +术语简称: + +TF: Google TensorFlow + +TF.NET: Tensorflow.NET \ No newline at end of file diff --git a/The Definitive Guide to Tensorflow.NET/assets/column-major order.png b/The Definitive Guide to Tensorflow.NET/assets/column-major order.png new file mode 100644 index 00000000..a03a5e0e Binary files /dev/null and b/The Definitive Guide to Tensorflow.NET/assets/column-major order.png differ diff --git a/The Definitive Guide to Tensorflow.NET/assets/row-major order.png b/The Definitive Guide to Tensorflow.NET/assets/row-major order.png new file mode 100644 index 00000000..92809513 Binary files /dev/null and b/The Definitive Guide to Tensorflow.NET/assets/row-major order.png differ diff --git a/src/TensorFlowNET.Core/Tensor/Tensor.cs b/src/TensorFlowNET.Core/Tensor/Tensor.cs index 4681e749..142671bb 100644 --- a/src/TensorFlowNET.Core/Tensor/Tensor.cs +++ b/src/TensorFlowNET.Core/Tensor/Tensor.cs @@ -7,50 +7,60 @@ namespace Tensorflow { public class Tensor { - private readonly Operation _op; - public Operation op => _op; - private readonly int _value_index; - public int value_index => _value_index; - private TF_DataType _dtype; - public TF_DataType dtype => _dtype; + public Operation op { get; } + public int value_index { get; } + public TF_DataType dtype { get; } - public Graph graph => _op.graph; + public Graph graph => op.graph; public string name; - - private readonly IntPtr _handle; - public IntPtr handle => _handle; - - private readonly int _ndim; - public int ndim => _ndim; + public IntPtr handle { get; } + public int ndim { get; } + public ulong bytesize { get; } + public ulong dataTypeSize { get;} + public ulong size => bytesize / dataTypeSize; + public IntPtr buffer { get; } public Tensor(IntPtr handle) { - _handle = handle; - _dtype = c_api.TF_TensorType(_handle); - _ndim = c_api.TF_NumDims(_handle); + this.handle = handle; + dtype = c_api.TF_TensorType(handle); + ndim = c_api.TF_NumDims(handle); + bytesize = c_api.TF_TensorByteSize(handle); + buffer = c_api.TF_TensorData(handle); + dataTypeSize = c_api.TF_DataTypeSize(dtype); } public Tensor(Operation op, int value_index, TF_DataType dtype) { - _op = op; - _value_index = value_index; - _dtype = dtype; + this.op = op; + this.value_index = value_index; + this.dtype = dtype; } public TF_Output _as_tf_output() { - return c_api_util.tf_output(_op._c_op, _value_index); + return c_api_util.tf_output(op._c_op, value_index); + } + + public T[] Data() + { + var data = new T[size]; + + for (ulong i = 0; i < size; i++) + { + data[i] = Marshal.PtrToStructure(buffer + (int)(i * dataTypeSize)); + } + + return data; } - public T Data() + public byte[] Data() { - /*var buffer = new byte[6 * sizeof(float)]; - var h1 = c_api.TF_TensorData(handle); - var bytes = Marshal.PtrToStructure(h1); - Marshal.Copy(h1, buffer, 0, 24);*/ + var data = new byte[bytesize]; + Marshal.Copy(buffer, data, 0, (int)bytesize); - return default(T); + return data; } } } diff --git a/src/TensorFlowNET.Core/c_api.cs b/src/TensorFlowNET.Core/c_api.cs index 4cdd0a5d..c1d30a86 100644 --- a/src/TensorFlowNET.Core/c_api.cs +++ b/src/TensorFlowNET.Core/c_api.cs @@ -17,6 +17,14 @@ namespace Tensorflow [DllImport(TensorFlowLibName)] public static unsafe extern void TF_AddInput(TF_OperationDescription desc, TF_Output input); + /// + /// returns the sizeof() for the underlying type corresponding to the given TF_DataType enum value. + /// + /// + /// + [DllImport(TensorFlowLibName)] + public static unsafe extern ulong TF_DataTypeSize(TF_DataType dt); + [DllImport(TensorFlowLibName)] public static unsafe extern void TF_DeleteSessionOptions(IntPtr opts); @@ -104,6 +112,14 @@ namespace Tensorflow [DllImport(TensorFlowLibName)] public static extern unsafe void TF_SetAttrType(TF_OperationDescription desc, string attr_name, TF_DataType value); + /// + /// Return the size of the underlying data in bytes. + /// + /// + /// + [DllImport(TensorFlowLibName)] + public static extern unsafe ulong TF_TensorByteSize(IntPtr tensor); + [DllImport(TensorFlowLibName)] public static extern unsafe IntPtr TF_TensorData(IntPtr tensor); diff --git a/test/TensorFlowNET.UnitTest/TensorTest.cs b/test/TensorFlowNET.UnitTest/TensorTest.cs index aea0b906..f337b583 100644 --- a/test/TensorFlowNET.UnitTest/TensorTest.cs +++ b/test/TensorFlowNET.UnitTest/TensorTest.cs @@ -36,6 +36,15 @@ namespace TensorFlowNET.UnitTest Assert.AreEqual(tensor.ndim, nd.ndim); Assert.AreEqual(nd.shape[0], c_api.TF_Dim(handle, 0)); Assert.AreEqual(nd.shape[1], c_api.TF_Dim(handle, 1)); + Assert.AreEqual(tensor.bytesize, (uint)nd.size * sizeof(float)); + + // Column major order + // https://en.wikipedia.org/wiki/File:Row_and_column_major_order.svg + // matrix:[[1, 2, 3], [4, 5, 6]] + // index: 0 2 4 1 3 5 + // result: 1 4 2 5 3 6 + var array = tensor.Data(); + Assert.IsTrue(Enumerable.SequenceEqual(nd.Data(), array)); } } }