Browse Source

finished tf.zeros #143

tags/v0.8.0
haiping008 6 years ago
parent
commit
b3497f31f2
11 changed files with 146 additions and 152 deletions
  1. +29
    -14
      src/TensorFlowNET.Core/Operations/OpDefLibrary.cs
  2. +3
    -3
      src/TensorFlowNET.Core/Operations/array_ops.py.cs
  3. +9
    -24
      src/TensorFlowNET.Core/Operations/gen_array_ops.cs
  4. +1
    -1
      src/TensorFlowNET.Core/Operations/gen_control_flow_ops.py.cs
  5. +8
    -44
      src/TensorFlowNET.Core/Operations/gen_math_ops.cs
  6. +20
    -0
      src/TensorFlowNET.Core/Python.cs
  7. +31
    -41
      src/TensorFlowNET.Core/Sessions/BaseSession.cs
  8. +11
    -1
      src/TensorFlowNET.Core/Sessions/Session.cs
  9. +2
    -4
      src/TensorFlowNET.Core/Variables/RefVariable.cs
  10. +2
    -14
      src/TensorFlowNET.Core/Variables/gen_state_ops.py.cs
  11. +30
    -6
      test/TensorFlowNET.UnitTest/ConstantTest.cs

+ 29
- 14
src/TensorFlowNET.Core/Operations/OpDefLibrary.cs View File

@@ -1,6 +1,7 @@
using NumSharp.Core;
using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Dynamic;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
@@ -10,8 +11,9 @@ namespace Tensorflow
{ {
public class OpDefLibrary public class OpDefLibrary
{ {
public Operation _apply_op_helper(string op_type_name, string name = "", Dictionary<string, object> keywords = null)
public Operation _apply_op_helper(string op_type_name, string name = "", dynamic args = null)
{ {
var keywords = ConvertToDict(args);
var g = ops.get_default_graph(); var g = ops.get_default_graph();
var op_def = g.GetOpDef(op_type_name); var op_def = g.GetOpDef(op_type_name);


@@ -20,9 +22,9 @@ namespace Tensorflow
name = op_type_name; name = op_type_name;


// Check for deprecation // Check for deprecation
if(op_def.Deprecation != null && op_def.Deprecation.Version > 0)
if (op_def.Deprecation != null && op_def.Deprecation.Version > 0)
{ {
} }


var default_type_attr_map = new Dictionary<string, object>(); var default_type_attr_map = new Dictionary<string, object>();
@@ -30,7 +32,7 @@ namespace Tensorflow
{ {
if (attr_def.Type != "type") continue; if (attr_def.Type != "type") continue;
var key = attr_def.Name; var key = attr_def.Name;
if(attr_def.DefaultValue != null)
if (attr_def.DefaultValue != null)
{ {
default_type_attr_map[key] = attr_def.DefaultValue.Type; default_type_attr_map[key] = attr_def.DefaultValue.Type;
} }
@@ -40,11 +42,9 @@ namespace Tensorflow
var inputs = new List<Tensor>(); var inputs = new List<Tensor>();
var input_types = new List<TF_DataType>(); var input_types = new List<TF_DataType>();


string scope = "";
using (var namescope = new ops.name_scope(name))
Operation op = null;
Python.with<ops.name_scope>(new ops.name_scope(name), scope =>
{ {
scope = namescope;

// Perform input type inference // Perform input type inference
foreach (var input_arg in op_def.InputArg) foreach (var input_arg in op_def.InputArg)
{ {
@@ -73,7 +73,7 @@ namespace Tensorflow
else else
{ {
var base_type = value.dtype.as_base_dtype(); var base_type = value.dtype.as_base_dtype();
input_types.Add(base_type); input_types.Add(base_type);
} }
} }
@@ -135,19 +135,34 @@ namespace Tensorflow
} }


// Add Op to graph // Add Op to graph
var op = g.create_op(op_type_name, inputs, output_types.ToArray(),
op = g.create_op(op_type_name, inputs, output_types.ToArray(),
name: scope, name: scope,
input_types: input_types.ToArray(), input_types: input_types.ToArray(),
attrs: attr_protos, attrs: attr_protos,
op_def: op_def); op_def: op_def);
});


return op;
}
return op;
} }


public DataType _MakeType(TF_DataType v, AttrDef attr_def) public DataType _MakeType(TF_DataType v, AttrDef attr_def)
{ {
return v.as_base_dtype().as_datatype_enum(); return v.as_base_dtype().as_datatype_enum();
} }

private Dictionary<string, object> ConvertToDict(dynamic dyn)
{
var dictionary = new Dictionary<string, object>();
foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(dyn))
{
object obj = propertyDescriptor.GetValue(dyn);
string name = propertyDescriptor.Name;
// avoid .net keyword
if (name == "_ref_")
name = "ref";
dictionary.Add(name, obj);
}
return dictionary;
}
} }
} }

+ 3
- 3
src/TensorFlowNET.Core/Operations/array_ops.py.cs View File

@@ -47,9 +47,9 @@ namespace Tensorflow
} }
else else
{ {
tShape = constant_op._tensor_shape_tensor_conversion_function(shape.as_shape(), dtype, name);
var c = constant_op.Constant(nd, name);
return gen_array_ops.fill<T>(shape, value, name);
tShape = constant_op._tensor_shape_tensor_conversion_function(shape.as_shape());
var c = constant_op.Constant(0);
return gen_array_ops.fill(tShape, c, name);
} }
} }
} }


+ 9
- 24
src/TensorFlowNET.Core/Operations/gen_array_ops.cs View File

@@ -14,11 +14,7 @@ namespace Tensorflow


public static Tensor placeholder(TF_DataType dtype, TensorShape shape = null, string name = "") public static Tensor placeholder(TF_DataType dtype, TensorShape shape = null, string name = "")
{ {
var keywords = new Dictionary<string, object>();
keywords.Add("dtype", dtype);
keywords.Add("shape", shape);

var _op = _op_def_lib._apply_op_helper("Placeholder", keywords: keywords);
var _op = _op_def_lib._apply_op_helper("Placeholder", args: new { dtype, shape });
var _result = _op.outputs; var _result = _op.outputs;
var _inputs_flat = _op.inputs; var _inputs_flat = _op.inputs;


@@ -38,20 +34,14 @@ namespace Tensorflow
/// <param name="name"></param> /// <param name="name"></param>
public static Tensor identity(Tensor input, string name = "") public static Tensor identity(Tensor input, string name = "")
{ {
var keywords = new Dictionary<string, object>();
keywords.Add("input", input);

var _op = _op_def_lib._apply_op_helper("Identity", name, keywords);
var _op = _op_def_lib._apply_op_helper("Identity", name, new { input });


return _op.outputs[0]; return _op.outputs[0];
} }


public static Tensor rank(Tensor input, string name = "") public static Tensor rank(Tensor input, string name = "")
{ {
var keywords = new Dictionary<string, object>();
keywords.Add("input", input);

var _op = _op_def_lib._apply_op_helper("Rank", name: name, keywords: keywords);
var _op = _op_def_lib._apply_op_helper("Rank", name: name, args: new { input });


return _op.outputs[0]; return _op.outputs[0];
} }
@@ -59,18 +49,13 @@ namespace Tensorflow
/// <summary> /// <summary>
/// Creates a tensor filled with a scalar value. /// Creates a tensor filled with a scalar value.
/// </summary> /// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dims"></param>
/// <param name="value"></param>
/// <param name="name"></param>
/// <returns></returns>
public static Tensor fill<T>(int[] dims, T value, string name = "")
/// <param name="dims">A `Tensor`.</param>
/// <param name="value">A `Tensor`.</param>
/// <param name="name">A name for the operation (optional).</param>
/// <returns>A `Tensor`. Has the same type as `value`.</returns>
public static Tensor fill(Tensor dims, Tensor value, string name = "")
{ {
var keywords = new Dictionary<string, object>();
keywords.Add("dims", dims);
keywords.Add("value", value);

var _op = _op_def_lib._apply_op_helper("Fill", name);
var _op = _op_def_lib._apply_op_helper("Fill", name, new { dims, value });


return _op.outputs[0]; return _op.outputs[0];
} }


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

@@ -10,7 +10,7 @@ namespace Tensorflow


public static Operation no_op(string name = "") public static Operation no_op(string name = "")
{ {
var _op = _op_def_lib._apply_op_helper("NoOp", name);
var _op = _op_def_lib._apply_op_helper("NoOp", name, null);


return _op; return _op;
} }


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

@@ -12,80 +12,49 @@ namespace Tensorflow


public static Tensor add(Tensor x, Tensor y) public static Tensor add(Tensor x, Tensor y)
{ {
var keywords = new Dictionary<string, object>();
keywords.Add("x", x);
keywords.Add("y", y);

var _op = _op_def_lib._apply_op_helper("Add", keywords: keywords);
var _op = _op_def_lib._apply_op_helper("Add", args: new { x, y });


return _op.outputs[0]; return _op.outputs[0];
} }


public static Tensor sub(Tensor x, Tensor y) public static Tensor sub(Tensor x, Tensor y)
{ {
var keywords = new Dictionary<string, object>();
keywords.Add("x", x);
keywords.Add("y", y);

var _op = _op_def_lib._apply_op_helper("Sub", name: "sub", keywords: keywords);
var _op = _op_def_lib._apply_op_helper("Sub", name: "sub", args: new { x, y });


return _op.outputs[0]; return _op.outputs[0];
} }


public static Tensor mul(Tensor x, Tensor y) public static Tensor mul(Tensor x, Tensor y)
{ {
var keywords = new Dictionary<string, object>();
keywords.Add("x", x);
keywords.Add("y", y);

var _op = _op_def_lib._apply_op_helper("Mul", keywords: keywords);
var _op = _op_def_lib._apply_op_helper("Mul", args: new { x, y });


return _op.outputs[0]; return _op.outputs[0];
} }


public static Tensor real_div(Tensor x, Tensor y) public static Tensor real_div(Tensor x, Tensor y)
{ {
var keywords = new Dictionary<string, object>();
keywords.Add("x", x);
keywords.Add("y", y);

var _op = _op_def_lib._apply_op_helper("RealDiv", name: "truediv", keywords: keywords);
var _op = _op_def_lib._apply_op_helper("RealDiv", name: "truediv", args: new { x, y });


return _op.outputs[0]; return _op.outputs[0];
} }


public static Tensor mat_mul(Tensor a, Tensor b, bool transpose_a = false, bool transpose_b = false) public static Tensor mat_mul(Tensor a, Tensor b, bool transpose_a = false, bool transpose_b = false)
{ {
var keywords = new Dictionary<string, object>();
keywords.Add("a", a);
keywords.Add("b", b);
keywords.Add("transpose_a", transpose_a);
keywords.Add("transpose_b", transpose_b);

var _op = _op_def_lib._apply_op_helper("MatMul", keywords: keywords);
var _op = _op_def_lib._apply_op_helper("MatMul", args: new { a, b, transpose_a, transpose_b });


return _op.outputs[0]; return _op.outputs[0];
} }


public static Tensor pow(Tensor x, double y) public static Tensor pow(Tensor x, double y)
{ {
var keywords = new Dictionary<string, object>();
keywords.Add("x", x);
keywords.Add("y", y);

var _op = _op_def_lib._apply_op_helper("Pow", keywords: keywords);
var _op = _op_def_lib._apply_op_helper("Pow", args: new { x, y });


return _op.outputs[0]; return _op.outputs[0];
} }


public static Tensor sum(Tensor input, Tensor axis = null) public static Tensor sum(Tensor input, Tensor axis = null)
{ {
var keywords = new Dictionary<string, object>();
keywords.Add("input", input);
keywords.Add("reduction_indices", axis);
keywords.Add("keep_dims", false);

var _op = _op_def_lib._apply_op_helper("Sum", keywords: keywords);
var _op = _op_def_lib._apply_op_helper("Sum", args: new { input, reduction_indices = axis, keep_dims = false });


return _op.outputs[0]; return _op.outputs[0];
} }
@@ -100,12 +69,7 @@ namespace Tensorflow
/// <returns></returns> /// <returns></returns>
public static Tensor range(Tensor start, Tensor limit, Tensor delta, string name = "") public static Tensor range(Tensor start, Tensor limit, Tensor delta, string name = "")
{ {
var keywords = new Dictionary<string, object>();
keywords.Add("start", start);
keywords.Add("limit", limit);
keywords.Add("delta", delta);

var _op = _op_def_lib._apply_op_helper("Range", name, keywords);
var _op = _op_def_lib._apply_op_helper("Range", name, new { start, limit, delta });


return _op.outputs[0]; return _op.outputs[0];
} }


+ 20
- 0
src/TensorFlowNET.Core/Python.cs View File

@@ -23,6 +23,26 @@ namespace Tensorflow
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.ToString());
throw ex;
}
finally
{
py.__exit__();
py.Dispose();
}
}

public static void with<T>(IPython py, Action<T> action) where T : IPython
{
try
{
py.__enter__();
action((T)py);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
throw ex; throw ex;
} }
finally finally


+ 31
- 41
src/TensorFlowNET.Core/Sessions/BaseSession.cs View File

@@ -125,57 +125,47 @@ namespace Tensorflow


for (int i = 0; i < fetch_list.Length; i++) for (int i = 0; i < fetch_list.Length; i++)
{ {
var tensor = new Tensor(output_values[i]);
switch (tensor.dtype)
{
case TF_DataType.TF_STRING:
{
// wired, don't know why we have to start from offset 9.
var bytes = tensor.Data();
var output = UTF8Encoding.Default.GetString(bytes, 9, bytes.Length - 9);
result[i] = fetchValue(tensor, output);
}
break;
case TF_DataType.TF_FLOAT:
{
var output = *(float*)c_api.TF_TensorData(output_values[i]);
result[i] = fetchValue(tensor, output);
}
break;
case TF_DataType.TF_INT16:
{
var output = *(short*)c_api.TF_TensorData(output_values[i]);
result[i] = fetchValue(tensor, output);
}
break;
case TF_DataType.TF_INT32:
{
var output = *(int*)c_api.TF_TensorData(output_values[i]);
result[i] = fetchValue(tensor, output);
}
break;
default:
throw new NotImplementedException("can't get output");
}
result[i] = fetchValue(output_values[i]);
} }


return result; return result;
} }


private NDArray fetchValue<T>(Tensor tensor, T output)
private unsafe NDArray fetchValue(IntPtr output)
{ {
NDArray nd;
var tensor = new Tensor(output);
NDArray nd = null;
Type type = tensor.dtype.as_numpy_datatype(); Type type = tensor.dtype.as_numpy_datatype();
var ndims = tensor.shape.Select(x => (int)x).ToArray(); var ndims = tensor.shape.Select(x => (int)x).ToArray();


if (tensor.NDims == 0)
{
nd = np.array(output).reshape();
}
else
switch (tensor.dtype)
{ {
nd = np.array(output).reshape(ndims);
case TF_DataType.TF_STRING:
var bytes = tensor.Data();
// wired, don't know why we have to start from offset 9.
var str = UTF8Encoding.Default.GetString(bytes, 9, bytes.Length - 9);
nd = np.array(str).reshape();
break;
case TF_DataType.TF_INT32:
var ints = new int[tensor.size];
for (ulong i = 0; i < tensor.size; i++)
ints[i] = *(int*)(c_api.TF_TensorData(output) + (int)(tensor.dataTypeSize * i));
nd = np.array(ints).reshape(ndims);
break;
case TF_DataType.TF_FLOAT:
var floats = new float[tensor.size];
for (ulong i = 0; i < tensor.size; i++)
floats[i] = *(float*)(c_api.TF_TensorData(output) + (int)(tensor.dataTypeSize * i));
nd = np.array(floats).reshape(ndims);
break;
case TF_DataType.TF_DOUBLE:
var doubles = new double[tensor.size];
for (ulong i = 0; i < tensor.size; i++)
doubles[i] = *(double*)(c_api.TF_TensorData(output) + (int)(tensor.dataTypeSize * i));
nd = np.array(doubles).reshape(ndims);
break;
default:
throw new NotImplementedException("can't fetch output");
} }


return nd; return nd;


+ 11
- 1
src/TensorFlowNET.Core/Sessions/Session.cs View File

@@ -4,7 +4,7 @@ using System.Text;


namespace Tensorflow namespace Tensorflow
{ {
public class Session : BaseSession, IDisposable
public class Session : BaseSession, IPython
{ {
private IntPtr _handle; private IntPtr _handle;
public Status Status { get; } public Status Status { get; }
@@ -41,5 +41,15 @@ namespace Tensorflow
Status.Dispose(); Status.Dispose();
c_api.TF_DeleteSession(_handle, Status); c_api.TF_DeleteSession(_handle, Status);
} }

public void __enter__()
{
}

public void __exit__()
{
}
} }
} }

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

@@ -65,10 +65,8 @@ namespace Tensorflow


ops.init_scope(); ops.init_scope();
var values = init_from_fn ? new List<object>() : new List<object> { initial_value }; var values = init_from_fn ? new List<object>() : new List<object> { initial_value };
using (var namescope = new ops.name_scope(name, "Variable", values))
Python.with<ops.name_scope>(new ops.name_scope(name, "Variable", values), scope =>
{ {
name = namescope;

if (init_from_fn) if (init_from_fn)
{ {


@@ -108,7 +106,7 @@ namespace Tensorflow
} }


ops.add_to_collections(collections, this); ops.add_to_collections(collections, this);
}
});
} }


public Tensor _ref() public Tensor _ref()


+ 2
- 14
src/TensorFlowNET.Core/Variables/gen_state_ops.py.cs View File

@@ -23,13 +23,7 @@ namespace Tensorflow
/// <returns></returns> /// <returns></returns>
public static Tensor variable_v2(long[] shape, TF_DataType dtype, string name = "", string container = "", string shared_name = "") public static Tensor variable_v2(long[] shape, TF_DataType dtype, string name = "", string container = "", string shared_name = "")
{ {
var keywords = new Dictionary<string, object>();
keywords.Add("dtype", dtype);
keywords.Add("shape", shape);
keywords.Add("container", container);
keywords.Add("shared_name", shared_name);

var _op = _op_def_lib._apply_op_helper("VariableV2", name: name, keywords: keywords);
var _op = _op_def_lib._apply_op_helper("VariableV2", name: name, args: new { dtype, shape, container, shared_name });


var _result = _op.outputs; var _result = _op.outputs;
var _inputs_flat = _op.inputs; var _inputs_flat = _op.inputs;
@@ -58,13 +52,7 @@ namespace Tensorflow
bool use_locking = true, bool use_locking = true,
string name = "") string name = "")
{ {
var keywords = new Dictionary<string, object>();
keywords.Add("ref", tensor);
keywords.Add("value", value);
keywords.Add("validate_shape", validate_shape);
keywords.Add("use_locking", use_locking);

var _op = _op_def_lib._apply_op_helper("Assign", name: name, keywords: keywords);
var _op = _op_def_lib._apply_op_helper("Assign", name: name, args: new { _ref_ = tensor, value, validate_shape, use_locking });


var _result = _op.outputs; var _result = _op.outputs;
var _inputs_flat = _op.inputs; var _inputs_flat = _op.inputs;


+ 30
- 6
test/TensorFlowNET.UnitTest/ConstantTest.cs View File

@@ -24,18 +24,42 @@ namespace TensorFlowNET.UnitTest
[TestMethod] [TestMethod]
public void StringConst() public void StringConst()
{ {
tensor = tf.constant("Elephant");
string str = "Hello, TensorFlow.NET!";
tensor = tf.constant(str);
Python.with<Session>(tf.Session(), sess =>
{
var result = sess.run(tensor);
Assert.IsTrue(result.Data<string>()[0] == str);
});
} }


[TestMethod] [TestMethod]
public void ZerosConst() public void ZerosConst()
{ {
tensor = tf.zeros(new Shape(3, 2), TF_DataType.TF_INT32, "x");
Assert.AreEqual(tensor.shape[0], 3);
Assert.AreEqual(tensor.shape[0], 2);
Assert.IsTrue(Enumerable.SequenceEqual(new int[] { 0, 0, 0, 0, 0, 0 }, tensor.Data<int>()));
// small size
tensor = tf.zeros(new Shape(3, 2), TF_DataType.TF_INT32, "small");
Python.with<Session>(tf.Session(), sess =>
{
var result = sess.run(tensor);

Assert.AreEqual(result.shape[0], 3);
Assert.AreEqual(result.shape[1], 2);
Assert.IsTrue(Enumerable.SequenceEqual(new int[] { 0, 0, 0, 0, 0, 0 }, result.Data<int>()));
});


tensor = tf.zeros(new Shape(200, 300), TF_DataType.TF_INT32, "x");
// big size
tensor = tf.zeros(new Shape(200, 100), TF_DataType.TF_INT32, "big");
Python.with<Session>(tf.Session(), sess =>
{
var result = sess.run(tensor);

Assert.AreEqual(result.shape[0], 200);
Assert.AreEqual(result.shape[1], 100);

var data = result.Data<int>();
Assert.AreEqual(0, data[0]);
Assert.AreEqual(0, data[result.size - 1]);
});
} }


[TestMethod] [TestMethod]


Loading…
Cancel
Save