Browse Source

Add FeedItem to hold feed session dictionary.

tags/v0.8.0
Oceania2018 6 years ago
parent
commit
7426fd0af0
18 changed files with 156 additions and 27 deletions
  1. +2
    -0
      docs/source/Attribute.md
  2. +2
    -0
      docs/source/EagerMode.md
  3. +2
    -0
      docs/source/Gradient.md
  4. +18
    -0
      docs/source/Placeholder.md
  5. +4
    -1
      docs/source/index.rst
  6. +2
    -2
      src/TensorFlowNET.Core/APIs/c_api.cs
  7. +14
    -4
      src/TensorFlowNET.Core/Sessions/BaseSession.cs
  8. +22
    -0
      src/TensorFlowNET.Core/Sessions/FeedItem.cs
  9. +1
    -1
      src/TensorFlowNET.Core/Tensors/Tensor.cs
  10. +36
    -0
      src/TensorFlowNET.Core/Tensors/c_api.tensor.cs
  11. +11
    -4
      src/TensorFlowNET.Core/Train/Optimizer.cs
  12. +1
    -1
      src/TensorFlowNET.Core/Variables/RefVariable.cs
  13. +1
    -1
      src/TensorFlowNET.Core/ops.py.cs
  14. +1
    -0
      src/TensorFlowNET.Core/tf.cs
  15. +8
    -7
      test/TensorFlowNET.Examples/BasicOperations.cs
  16. +15
    -0
      test/TensorFlowNET.UnitTest/ConstantTest.cs
  17. +5
    -5
      test/TensorFlowNET.UnitTest/OperationsTest.cs
  18. +11
    -1
      test/TensorFlowNET.UnitTest/PlaceholderTest.cs

+ 2
- 0
docs/source/Attribute.md View File

@@ -0,0 +1,2 @@
# Chapter. Attribute


+ 2
- 0
docs/source/EagerMode.md View File

@@ -0,0 +1,2 @@
# Chapter. Eager Mode


+ 2
- 0
docs/source/Gradient.md View File

@@ -0,0 +1,2 @@
# Chapter. Gradient


+ 18
- 0
docs/source/Placeholder.md View File

@@ -1,2 +1,20 @@
# Chapter. Placeholder

In this chapter we will talk about another common data type in TensorFlow: Placeholder. It is a simplified variable that can be passed to the required value by the session when the graph is run, that is, when you build the graph, you don't need to specify the value of that variable, but delay the session to the beginning. In TensorFlow terminology, we then feed data into the graph through these placeholders. The difference between placeholders and constants is that placeholders can specify coefficient values more flexibly without modifying the code that builds the graph. For example, mathematical constants are suitable for Constant, and some model smoothing values can be specified with Placeholder.

这章我们讲一下TensorFlow里的另一种常用数据类型:占位符。它是一种简化的变量,可以在图运行的时候由会话传入所需要的值,就是说你在构建图的时候,不需要具体指定那个变量的值,而是延迟到会话开始的时候以参数的方式从外部传入初始值。占位符和常量的区别是占位符可以更灵活的指定系数值,而不需要修改构建图的代码。比如数学常量就适合用Constant, 有些模型平滑值可以用Placeholder来指定。

```csharp
var x = tf.placeholder(tf.int32);
var y = x * 3;

Python.with<Session>(tf.Session(), sess =>
{
var result = sess.run(y, feed_dict: new FeedItem[]
{
new FeedItem(x, 2)
});
// (int)result should be 6;
});
```


+ 4
- 1
docs/source/index.rst View File

@@ -19,6 +19,9 @@ Welcome to TensorFlow.NET's documentation!
Constant
Placeholder
Variable
Attribute
Operation
Graph
Session
Session
Gradient
EagerMode

+ 2
- 2
src/TensorFlowNET.Core/APIs/c_api.cs View File

@@ -21,8 +21,8 @@ namespace Tensorflow
/// const char* => string
/// int32_t => int
/// int64_t* => long[]
/// size_t* => unlong[]
/// size_t* => ref uint
/// size_t* => ulong[]
/// size_t* => ref ulong
/// void* => IntPtr
/// string => IntPtr c_api.StringPiece(IntPtr)
/// unsigned char => byte


+ 14
- 4
src/TensorFlowNET.Core/Sessions/BaseSession.cs View File

@@ -35,14 +35,24 @@ namespace Tensorflow
c_api.TF_DeleteSessionOptions(opts);
}

public virtual NDArray run(Tensor fetches, Dictionary<Tensor, NDArray> feed_dict = null)
public virtual NDArray run(Tensor fetches, FeedItem[] feed_dict = null)
{
return _run(fetches, feed_dict);
var feed = new Dictionary<Tensor, NDArray>();

if (feed_dict != null)
feed_dict.ToList().ForEach(x => feed.Add(x.Key, x.Value));

return _run(fetches, feed);
}

public virtual NDArray run(Operation fetches, Dictionary<Tensor, NDArray> feed_dict = null)
public virtual NDArray run(Operation fetches, FeedItem[] feed_dict = null)
{
return _run(fetches, feed_dict);
var feed = new Dictionary<Tensor, NDArray>();

if (feed_dict != null)
feed_dict.ToList().ForEach(x => feed.Add(x.Key, x.Value));

return _run(fetches, feed);
}

private NDArray _run<T>(T fetches, Dictionary<Tensor, NDArray> feed_dict = null)


+ 22
- 0
src/TensorFlowNET.Core/Sessions/FeedItem.cs View File

@@ -0,0 +1,22 @@
using NumSharp.Core;
using System;
using System.Collections.Generic;
using System.Text;

namespace Tensorflow
{
/// <summary>
/// Feed dictionary item
/// </summary>
public class FeedItem
{
public Tensor Key { get; }
public NDArray Value { get; }

public FeedItem(Tensor tensor, NDArray nd)
{
Key = tensor;
Value = nd;
}
}
}

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

@@ -213,7 +213,7 @@ namespace Tensorflow
/// <param name="feed_dict">A dictionary that maps `Tensor` objects to feed values.</param>
/// <param name="session">The `Session` to be used to evaluate this tensor.</param>
/// <returns></returns>
public NDArray eval(Dictionary<Tensor, NDArray> feed_dict = null, Session session = null)
public NDArray eval(FeedItem[] feed_dict = null, Session session = null)
{
return ops._eval_using_default_session(this, feed_dict, Graph, session);
}


+ 36
- 0
src/TensorFlowNET.Core/Tensors/c_api.tensor.cs View File

@@ -97,5 +97,41 @@ namespace Tensorflow
/// <returns></returns>
[DllImport(TensorFlowLibName)]
public static extern TF_DataType TF_TensorType(IntPtr tensor);

/// <summary>
/// Return the size in bytes required to encode a string `len` bytes long into a
/// TF_STRING tensor.
/// </summary>
/// <param name="len">size_t</param>
/// <returns></returns>
[DllImport(TensorFlowLibName)]
public static extern ulong TF_StringEncodedSize(ulong len);

/// <summary>
/// Encode the string `src` (`src_len` bytes long) into `dst` in the format
/// required by TF_STRING tensors. Does not write to memory more than `dst_len`
/// bytes beyond `*dst`. `dst_len` should be at least
/// TF_StringEncodedSize(src_len).
/// </summary>
/// <param name="src">const char*</param>
/// <param name="src_len">size_t</param>
/// <param name="dst">char*</param>
/// <param name="dst_len">size_t</param>
/// <param name="status">TF_Status*</param>
/// <returns>On success returns the size in bytes of the encoded string.</returns>
[DllImport(TensorFlowLibName)]
public static extern ulong TF_StringEncode(string src, ulong src_len, string dst, ulong dst_len, IntPtr status);

/// <summary>
/// Decode a string encoded using TF_StringEncode.
/// </summary>
/// <param name="src">const char*</param>
/// <param name="src_len">size_t</param>
/// <param name="dst">const char**</param>
/// <param name="dst_len">size_t*</param>
/// <param name="status">TF_Status*</param>
/// <returns></returns>
[DllImport(TensorFlowLibName)]
public static extern ulong TF_StringDecode(string src, ulong src_len, IntPtr dst, ref ulong dst_len, IntPtr status);
}
}

+ 11
- 4
src/TensorFlowNET.Core/Train/Optimizer.cs View File

@@ -39,16 +39,19 @@ namespace Tensorflow
/// Add operations to minimize `loss` by updating `var_list`
/// </summary>
/// <param name="loss"></param>
/// <returns></returns>
public Optimizer minimize(Tensor loss,
/// <returns>
/// An Operation that updates the variables in `var_list`. If `global_step`
/// was not `None`, that operation also increments `global_step`.
/// </returns>
public Operation minimize(Tensor loss,
GateGradientType gate_gradients = GateGradientType.GATE_OP,
bool colocate_gradients_with_ops = false)
{
compute_gradients(loss,
var grads_and_vars = compute_gradients(loss,
gate_gradients: gate_gradients,
colocate_gradients_with_ops: colocate_gradients_with_ops);

return this;
return null;
}

/// <summary>
@@ -56,6 +59,10 @@ namespace Tensorflow
/// </summary>
/// <param name="loss"></param>
/// <param name="gate_gradients"></param>
/// <returns>
/// A list of (gradient, variable) pairs. Variable is always present, but
/// gradient can be `None`.
/// </returns>
public List<KeyValuePair<object, object>> compute_gradients(Tensor loss,
List<RefVariable> var_list = null,
int? aggregation_method = null,


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

@@ -78,7 +78,7 @@ namespace Tensorflow

var shape = _initial_value.shape;
dtype = _initial_value.dtype;
_variable = gen_state_ops.variable_v2(shape, dtype.as_base_dtype(), name);
_variable = gen_state_ops.variable_v2(shape, dtype.as_base_dtype(), scope);
}

// Manually overrides the variable's shape with the initial value's.


+ 1
- 1
src/TensorFlowNET.Core/ops.py.cs View File

@@ -240,7 +240,7 @@ namespace Tensorflow
/// of numpy ndarrays that each correspond to the respective element in
/// "tensors".
/// </returns>
public static NDArray _eval_using_default_session(Tensor tensor, Dictionary<Tensor, NDArray> feed_dict, Graph graph, Session session = null)
public static NDArray _eval_using_default_session(Tensor tensor, FeedItem[] feed_dict, Graph graph, Session session = null)
{
if (session == null)
{


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

@@ -8,6 +8,7 @@ namespace Tensorflow
public static partial class tf
{
public static TF_DataType int16 = TF_DataType.TF_INT16;
public static TF_DataType int32 = TF_DataType.TF_INT32;
public static TF_DataType float16 = TF_DataType.TF_HALF;
public static TF_DataType float32 = TF_DataType.TF_FLOAT;
public static TF_DataType float64 = TF_DataType.TF_DOUBLE;


+ 8
- 7
test/TensorFlowNET.Examples/BasicOperations.cs View File

@@ -44,9 +44,11 @@ namespace TensorFlowNET.Examples
// Launch the default graph.
using(sess = tf.Session())
{
var feed_dict = new Dictionary<Tensor, NDArray>();
feed_dict.Add(a, (short)2);
feed_dict.Add(b, (short)3);
var feed_dict = new FeedItem[]
{
new FeedItem(a, (short)2),
new FeedItem(b, (short)3)
};
// Run every operation with variable input
Console.WriteLine($"Addition with variables: {sess.run(add, feed_dict)}");
Console.WriteLine($"Multiplication with variables: {sess.run(mul, feed_dict)}");
@@ -87,12 +89,11 @@ namespace TensorFlowNET.Examples
using (sess = tf.Session())
{
var result = sess.run(product);
Console.WriteLine(result.ToString());
if(result.Data<int>()[0] != 12)
Console.WriteLine(result.ToString()); // ==> [[ 12.]]
if (result.Data<int>()[0] != 12)
{
throw new Exception("BasicOperations error");
throw new ValueError("BasicOperations");
}
// ==> [[ 12.]]
}
}
}


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

@@ -11,6 +11,8 @@ namespace TensorFlowNET.UnitTest
[TestClass]
public class ConstantTest
{
Status status = new Status();

[TestMethod]
public void ScalarConst()
{
@@ -94,5 +96,18 @@ namespace TensorFlowNET.UnitTest

Assert.AreEqual(6.0, result);
}

[TestMethod]
public void StringEncode()
{
string str = "Hello, TensorFlow.NET!";
ulong dst_len = c_api.TF_StringEncodedSize((ulong)str.Length);
Assert.AreEqual(dst_len, (ulong)23);
string dst = "";
c_api.TF_StringEncode(str, (ulong)str.Length, dst, dst_len, status);
Assert.AreEqual(status.Code, TF_Code.TF_OK);

//c_api.TF_StringDecode(str, (ulong)str.Length, IntPtr.Zero, ref dst_len, status);
}
}
}

+ 5
- 5
test/TensorFlowNET.UnitTest/OperationsTest.cs View File

@@ -32,11 +32,11 @@ namespace TensorFlowNET.UnitTest

using(var sess = tf.Session())
{
var feed_dict = new Dictionary<Tensor, NDArray>();
feed_dict.Add(a, 3.0f);
feed_dict.Add(b, 2.0f);
var o = sess.run(c, feed_dict);
var o = sess.run(c, feed_dict: new FeedItem[]
{
new FeedItem(a, 3.0f),
new FeedItem(b, 2.0f)
});
Assert.AreEqual((float)o, 5.0f);
}
}


+ 11
- 1
test/TensorFlowNET.UnitTest/PlaceholderTest.cs View File

@@ -12,7 +12,17 @@ namespace TensorFlowNET.UnitTest
[TestMethod]
public void placeholder()
{
var x = tf.placeholder(tf.float32);
var x = tf.placeholder(tf.int32);
var y = x * 3;

Python.with<Session>(tf.Session(), sess =>
{
var result = sess.run(y, feed_dict: new FeedItem[]
{
new FeedItem(x, 2)
});
Assert.AreEqual((int)result, 6);
});
}
}
}

Loading…
Cancel
Save