diff --git a/src/TensorFlowNET.Core/APIs/tf.math.cs b/src/TensorFlowNET.Core/APIs/tf.math.cs
index 6ee90749..bbf240e3 100644
--- a/src/TensorFlowNET.Core/APIs/tf.math.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.math.cs
@@ -54,6 +54,24 @@ namespace Tensorflow
public static Tensor ceil(Tensor x, string name = null)
=> gen_math_ops.ceil(x, name);
+ ///
+ /// Computes sin of x element-wise.
+ ///
+ ///
+ ///
+ ///
+ public static Tensor sin(Tensor x, string name = null)
+ => gen_math_ops.sin(x, name);
+
+ ///
+ /// Computes hyperbolic sine of x element-wise.
+ ///
+ ///
+ ///
+ ///
+ public static Tensor sinh(Tensor x, string name = null)
+ => gen_math_ops.sinh(x, name);
+
///
/// Computes cos of x element-wise.
///
@@ -72,6 +90,12 @@ namespace Tensorflow
public static Tensor cosh(Tensor x, string name = null)
=> gen_math_ops.cosh(x, name);
+ public static Tensor tan(Tensor x, string name = null)
+ => gen_math_ops.tan(x, name);
+
+ public static Tensor tanh(Tensor x, string name = null)
+ => gen_math_ops.tanh(x, name);
+
///
/// Returns element-wise largest integer not greater than x.
///
@@ -257,6 +281,9 @@ namespace Tensorflow
return math_ops.reduce_sum(input, axis);
}
+ public static Tensor sum(Tensor input, int axis, bool keep_dims = false, string name = null)
+ => gen_math_ops._sum(input, axis, keep_dims: keep_dims, name: name);
+
public static Tensor reduce_mean(Tensor input_tensor, int[] axis = null, bool keepdims = false, string name = null, int? reduction_indices = null)
=> math_ops.reduce_mean(input_tensor, axis: axis, keepdims: keepdims, name: name, reduction_indices: reduction_indices);
diff --git a/src/TensorFlowNET.Core/Clustering/_InitializeClustersOpFactory.cs b/src/TensorFlowNET.Core/Clustering/_InitializeClustersOpFactory.cs
index 14393708..54edf83b 100644
--- a/src/TensorFlowNET.Core/Clustering/_InitializeClustersOpFactory.cs
+++ b/src/TensorFlowNET.Core/Clustering/_InitializeClustersOpFactory.cs
@@ -52,13 +52,6 @@ namespace Tensorflow.Clustering
_num_data = math_ops.add_n(_inputs.Select(i => array_ops.shape(i)[0]).ToArray());
}
- public Tensor[] op()
- {
- return control_flow_ops.cond(gen_math_ops.equal(_num_remaining, 0),
- () => new Operation[] { check_ops.assert_equal(_cluster_centers_initialized, true) },
- _initialize);
- }
-
private Operation[] _initialize()
{
with(ops.control_dependencies(new Operation[]
@@ -72,6 +65,17 @@ namespace Tensorflow.Clustering
throw new NotImplementedException("_InitializeClustersOpFactory _initialize");
}
+ public Tensor[] op()
+ {
+ return control_flow_ops.cond(gen_math_ops.equal(_num_remaining, 0),
+ () =>
+ {
+ var op = check_ops.assert_equal(_cluster_centers_initialized, true);
+ return new Operation[] { op };
+ },
+ _initialize);
+ }
+
/*private int _add_new_centers()
{
var new_centers = _choose_initial_centers();
diff --git a/src/TensorFlowNET.Core/Operations/Operation.Control.cs b/src/TensorFlowNET.Core/Operations/Operation.Control.cs
index 39a011a8..812ca9fb 100644
--- a/src/TensorFlowNET.Core/Operations/Operation.Control.cs
+++ b/src/TensorFlowNET.Core/Operations/Operation.Control.cs
@@ -25,7 +25,7 @@ namespace Tensorflow
public void _add_control_input(Operation op)
{
- c_api.TF_AddControlInput(_handle, op);
+ c_api.TF_AddControlInput(_operDesc, op);
}
public void _add_control_inputs(Operation[] ops)
diff --git a/src/TensorFlowNET.Core/Operations/Operation.cs b/src/TensorFlowNET.Core/Operations/Operation.cs
index 0979c150..b6952540 100644
--- a/src/TensorFlowNET.Core/Operations/Operation.cs
+++ b/src/TensorFlowNET.Core/Operations/Operation.cs
@@ -11,6 +11,7 @@ namespace Tensorflow
public partial class Operation : ITensorOrOperation
{
private readonly IntPtr _handle; // _c_op in python
+ private readonly IntPtr _operDesc;
private Graph _graph;
//[JsonIgnore]
@@ -58,9 +59,9 @@ namespace Tensorflow
{
_graph = g;
- var desc = c_api.TF_NewOperation(g, opType, oper_name);
- c_api.TF_SetAttrType(desc, "dtype", TF_DataType.TF_INT32);
- c_api.TF_FinishOperation(desc, status);
+ _operDesc = c_api.TF_NewOperation(g, opType, oper_name);
+ c_api.TF_SetAttrType(_operDesc, "dtype", TF_DataType.TF_INT32);
+ _handle = c_api.TF_FinishOperation(_operDesc, status);
}
///
@@ -112,7 +113,7 @@ namespace Tensorflow
op_def = g.GetOpDef(node_def.Op);
var grouped_inputs = _reconstruct_sequence_inputs(op_def, inputs, node_def.Attr);
- _handle = ops._create_c_op(g, node_def, grouped_inputs, control_input_ops.ToArray());
+ (_handle, _operDesc) = ops._create_c_op(g, node_def, grouped_inputs, control_input_ops.ToArray());
// Initialize self._outputs.
output_types = new TF_DataType[NumOutputs];
diff --git a/src/TensorFlowNET.Core/Operations/check_ops.cs b/src/TensorFlowNET.Core/Operations/check_ops.cs
index 169cb333..8f395223 100644
--- a/src/TensorFlowNET.Core/Operations/check_ops.cs
+++ b/src/TensorFlowNET.Core/Operations/check_ops.cs
@@ -12,12 +12,29 @@ namespace Tensorflow
///
///
///
- public static Operation assert_equal(object t1, object t2, object[] data = null, string name = null)
+ public static Operation assert_equal(object t1, object t2, object[] data = null, string message = null, string name = null)
{
+ if (message == null)
+ message = "";
+
return with(ops.name_scope(name, "assert_equal", new { t1, t2, data }), delegate
{
var x = ops.convert_to_tensor(t1, name: "x");
var y = ops.convert_to_tensor(t2, name: "y");
+
+ if (data == null)
+ {
+ data = new object[]
+ {
+ message,
+ "Condition x == y did not hold element-wise:",
+ $"x (%s) = {x.name}",
+ x,
+ $"y (%s) = {y.name}",
+ y
+ };
+ }
+
var condition = math_ops.reduce_all(gen_math_ops.equal(x, y));
var x_static = tensor_util.constant_value(x);
var y_static = tensor_util.constant_value(y);
diff --git a/src/TensorFlowNET.Core/Operations/control_flow_ops.py.cs b/src/TensorFlowNET.Core/Operations/control_flow_ops.py.cs
index 79416930..8ed7c17e 100644
--- a/src/TensorFlowNET.Core/Operations/control_flow_ops.py.cs
+++ b/src/TensorFlowNET.Core/Operations/control_flow_ops.py.cs
@@ -16,14 +16,16 @@ namespace Tensorflow
name = scope;
var xs = ops.convert_n_to_tensor(data);
condition = ops.convert_to_tensor(condition, name: "Condition");
- Func true_assert = () => new Operation[]
+ Func true_assert = () =>
{
- gen_logging_ops._assert(condition, data, summarize, name: "Assert")
+ var assert = gen_logging_ops._assert(condition, data, summarize, name: "Assert");
+ return new Operation[] { assert };
};
- Func false_assert = () => new Operation[]
+ Func false_assert = () =>
{
- gen_control_flow_ops.no_op()
+ var op = gen_control_flow_ops.no_op();
+ return new Operation[] { op };
};
var guarded_assert = cond(condition, false_assert, true_assert, name: "AssertGuard");
diff --git a/src/TensorFlowNET.Core/Operations/gen_math_ops.cs b/src/TensorFlowNET.Core/Operations/gen_math_ops.cs
index 25ae46ed..c562586a 100644
--- a/src/TensorFlowNET.Core/Operations/gen_math_ops.cs
+++ b/src/TensorFlowNET.Core/Operations/gen_math_ops.cs
@@ -101,6 +101,20 @@ namespace Tensorflow
return _op.outputs[0];
}
+ public static Tensor sin(Tensor x, string name = null)
+ {
+ var _op = _op_def_lib._apply_op_helper("Sin", name, args: new { x });
+
+ return _op.outputs[0];
+ }
+
+ public static Tensor sinh(Tensor x, string name = null)
+ {
+ var _op = _op_def_lib._apply_op_helper("Sinh", name, args: new { x });
+
+ return _op.outputs[0];
+ }
+
public static Tensor cos(Tensor x, string name = null)
{
var _op = _op_def_lib._apply_op_helper("Cos", name, args: new { x });
@@ -115,6 +129,20 @@ namespace Tensorflow
return _op.outputs[0];
}
+ public static Tensor tan(Tensor x, string name = null)
+ {
+ var _op = _op_def_lib._apply_op_helper("Tan", name, args: new { x });
+
+ return _op.outputs[0];
+ }
+
+ public static Tensor tanh(Tensor x, string name = null)
+ {
+ var _op = _op_def_lib._apply_op_helper("Tanh", name, args: new { x });
+
+ return _op.outputs[0];
+ }
+
public static Tensor floor(Tensor x, string name = null)
{
var _op = _op_def_lib._apply_op_helper("Floor", name, args: new { x });
diff --git a/src/TensorFlowNET.Core/Tensors/dtypes.cs b/src/TensorFlowNET.Core/Tensors/dtypes.cs
index f14affbc..34d6a8f7 100644
--- a/src/TensorFlowNET.Core/Tensors/dtypes.cs
+++ b/src/TensorFlowNET.Core/Tensors/dtypes.cs
@@ -10,6 +10,8 @@ namespace Tensorflow
{
switch (type)
{
+ case TF_DataType.TF_BOOL:
+ return typeof(bool);
case TF_DataType.TF_INT32:
return typeof(int);
case TF_DataType.TF_INT16:
diff --git a/src/TensorFlowNET.Core/Tensors/tensor_util.cs b/src/TensorFlowNET.Core/Tensors/tensor_util.cs
index 870db57b..a2830fc1 100644
--- a/src/TensorFlowNET.Core/Tensors/tensor_util.cs
+++ b/src/TensorFlowNET.Core/Tensors/tensor_util.cs
@@ -47,16 +47,23 @@ namespace Tensorflow
var tensor_dtype = tensor.Dtype.as_numpy_dtype();
if (tensor.TensorContent.Length > 0)
- return np.frombuffer(tensor.TensorContent.ToByteArray(), tensor_dtype)
- .reshape(shape);
+ {
+ return np.frombuffer(tensor.TensorContent.ToByteArray(), tensor_dtype).reshape(shape);
+ }
else if (tensor.Dtype == DataType.DtHalf || tensor.Dtype == DataType.DtBfloat16)
;
else if (tensor.Dtype == DataType.DtFloat)
;
else if (new DataType[] { DataType.DtInt32, DataType.DtUint8 }.Contains(tensor.Dtype))
+ {
if (tensor.IntVal.Count == 1)
- return np.repeat(np.array(tensor.IntVal[0]), Convert.ToInt32(num_elements))
- .reshape(shape);
+ return np.repeat(np.array(tensor.IntVal[0]), num_elements).reshape(shape);
+ }
+ else if (tensor.Dtype == DataType.DtBool)
+ {
+ if (tensor.BoolVal.Count == 1)
+ return np.repeat(np.array(tensor.BoolVal[0]), num_elements).reshape(shape);
+ }
throw new NotImplementedException("MakeNdarray");
}
diff --git a/src/TensorFlowNET.Core/Variables/RefVariable.cs b/src/TensorFlowNET.Core/Variables/RefVariable.cs
index e7ee3043..8d20f34d 100644
--- a/src/TensorFlowNET.Core/Variables/RefVariable.cs
+++ b/src/TensorFlowNET.Core/Variables/RefVariable.cs
@@ -265,7 +265,7 @@ namespace Tensorflow
public override string ToString()
{
- return $"tf.Variable '{name}' shape={shape} dtype={dtype}";
+ return $"tf.RefVariable '{name}' shape={shape} dtype={dtype}";
}
public VariableDef to_proto(string export_scope)
diff --git a/src/TensorFlowNET.Core/ops.py.cs b/src/TensorFlowNET.Core/ops.py.cs
index 2c672d42..43a3c9ba 100644
--- a/src/TensorFlowNET.Core/ops.py.cs
+++ b/src/TensorFlowNET.Core/ops.py.cs
@@ -122,7 +122,7 @@ namespace Tensorflow
///
/// A list of `Operation`s to set as control dependencies.
/// A wrapped TF_Operation*.
- public static IntPtr _create_c_op(Graph graph, NodeDef node_def, T[] inputs, Operation[] control_inputs)
+ public static (IntPtr, IntPtr) _create_c_op(Graph graph, NodeDef node_def, T[] inputs, Operation[] control_inputs)
{
var op_desc = graph.NewOperation(node_def.Op, node_def.Name);
@@ -164,7 +164,7 @@ namespace Tensorflow
status.Check(true);
- return c_op;
+ return (c_op, op_desc);
}
public static OpDef _get_op_def(Graph graph, string type)
diff --git a/test/TensorFlowNET.Examples/KMeansClustering.cs b/test/TensorFlowNET.Examples/KMeansClustering.cs
index ece7623d..93fae200 100644
--- a/test/TensorFlowNET.Examples/KMeansClustering.cs
+++ b/test/TensorFlowNET.Examples/KMeansClustering.cs
@@ -16,7 +16,7 @@ namespace TensorFlowNET.Examples
public class KMeansClustering : Python, IExample
{
public int Priority => 8;
- public bool Enabled => false;
+ public bool Enabled => true;
public string Name => "K-means Clustering";
Datasets mnist;