| @@ -53,7 +53,17 @@ namespace Tensorflow.Clustering | |||||
| var initial_clusters = _initial_clusters; | var initial_clusters = _initial_clusters; | ||||
| var num_clusters = ops.convert_to_tensor(_num_clusters); | var num_clusters = ops.convert_to_tensor(_num_clusters); | ||||
| var inputs = _inputs; | var inputs = _inputs; | ||||
| _create_variables(num_clusters); | |||||
| var vars = _create_variables(num_clusters); | |||||
| var cluster_centers_var = vars[0]; | |||||
| var cluster_centers_initialized = vars[1]; | |||||
| var total_counts = vars[2]; | |||||
| var cluster_centers_updated = vars[3]; | |||||
| var update_in_steps = vars[4]; | |||||
| var init_op = new _InitializeClustersOpFactory(_inputs, num_clusters, initial_clusters, _distance_metric, | |||||
| _random_seed, _kmeans_plus_plus_num_retries, | |||||
| _kmc2_chain_length, cluster_centers_var, cluster_centers_updated, | |||||
| cluster_centers_initialized).op(); | |||||
| throw new NotImplementedException("KMeans training_graph"); | throw new NotImplementedException("KMeans training_graph"); | ||||
| } | } | ||||
| @@ -0,0 +1,62 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| namespace Tensorflow.Clustering | |||||
| { | |||||
| /// <summary> | |||||
| /// Internal class to create the op to initialize the clusters. | |||||
| /// </summary> | |||||
| public class _InitializeClustersOpFactory | |||||
| { | |||||
| Tensor[] _inputs; | |||||
| Tensor _num_clusters; | |||||
| IInitializer _initial_clusters; | |||||
| string _distance_metric; | |||||
| int _random_seed; | |||||
| int _kmeans_plus_plus_num_retries; | |||||
| int _kmc2_chain_length; | |||||
| RefVariable _cluster_centers; | |||||
| RefVariable _cluster_centers_updated; | |||||
| RefVariable _cluster_centers_initialized; | |||||
| Tensor _num_selected; | |||||
| Tensor _num_remaining; | |||||
| Tensor _num_data; | |||||
| public _InitializeClustersOpFactory(Tensor[] inputs, | |||||
| Tensor num_clusters, | |||||
| IInitializer initial_clusters, | |||||
| string distance_metric, | |||||
| int random_seed, | |||||
| int kmeans_plus_plus_num_retries, | |||||
| int kmc2_chain_length, | |||||
| RefVariable cluster_centers, | |||||
| RefVariable cluster_centers_updated, | |||||
| RefVariable cluster_centers_initialized) | |||||
| { | |||||
| _inputs = inputs; | |||||
| _num_clusters = num_clusters; | |||||
| _initial_clusters = initial_clusters; | |||||
| _distance_metric = distance_metric; | |||||
| _random_seed = random_seed; | |||||
| _kmeans_plus_plus_num_retries = kmeans_plus_plus_num_retries; | |||||
| _kmc2_chain_length = kmc2_chain_length; | |||||
| _cluster_centers = cluster_centers; | |||||
| _cluster_centers_updated = cluster_centers_updated; | |||||
| _cluster_centers_initialized = cluster_centers_initialized; | |||||
| _num_selected = array_ops.shape(_cluster_centers)[0]; | |||||
| _num_remaining = _num_clusters - _num_selected; | |||||
| _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) }, | |||||
| () => new Operation[0]); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,28 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Text; | |||||
| namespace Tensorflow | |||||
| { | |||||
| public class check_ops : Python | |||||
| { | |||||
| /// <summary> | |||||
| /// Assert the condition `x == y` holds element-wise. | |||||
| /// </summary> | |||||
| /// <param name="t1"></param> | |||||
| /// <param name="t2"></param> | |||||
| /// <param name="name"></param> | |||||
| public static Operation assert_equal(object t1, object t2, object[] data = null, string name = null) | |||||
| { | |||||
| 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"); | |||||
| 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); | |||||
| return control_flow_ops.Asset(condition, data); | |||||
| }); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -9,6 +9,29 @@ namespace Tensorflow | |||||
| { | { | ||||
| public class control_flow_ops : Python | public class control_flow_ops : Python | ||||
| { | { | ||||
| public static Operation Asset(Tensor condition, object[] data, int? summarize = null, string name = null) | |||||
| { | |||||
| return with(ops.name_scope(name, "Assert", new { condition, data }), scope => | |||||
| { | |||||
| name = scope; | |||||
| var xs = ops.convert_n_to_tensor(data); | |||||
| condition = ops.convert_to_tensor(condition, name: "Condition"); | |||||
| Func<Operation[]> true_assert = () => new Operation[] | |||||
| { | |||||
| gen_logging_ops._assert(condition, data, summarize, name: "Assert") | |||||
| }; | |||||
| Func<Operation[]> false_assert = () => new Operation[] | |||||
| { | |||||
| gen_control_flow_ops.no_op() | |||||
| }; | |||||
| var guarded_assert = cond(condition, false_assert, true_assert, name: "AssertGuard"); | |||||
| return guarded_assert[0].op; | |||||
| }); | |||||
| } | |||||
| public static Operation group<T>(T[] inputs, string name = null) where T : ITensorOrOperation | public static Operation group<T>(T[] inputs, string name = null) where T : ITensorOrOperation | ||||
| { | { | ||||
| return with(ops.name_scope(name, "group_deps", inputs), scope => | return with(ops.name_scope(name, "group_deps", inputs), scope => | ||||
| @@ -0,0 +1,21 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Text; | |||||
| namespace Tensorflow | |||||
| { | |||||
| public class gen_logging_ops | |||||
| { | |||||
| public static OpDefLibrary _op_def_lib = new OpDefLibrary(); | |||||
| public static Operation _assert(Tensor condition, object[] data, int? summarize = 3, string name = null) | |||||
| { | |||||
| if (!summarize.HasValue) | |||||
| summarize = 3; | |||||
| var _op = _op_def_lib._apply_op_helper("Assert", name, args: new { condition, data, summarize }); | |||||
| return _op; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -10,6 +10,13 @@ namespace Tensorflow | |||||
| { | { | ||||
| public static OpDefLibrary _op_def_lib = new OpDefLibrary(); | public static OpDefLibrary _op_def_lib = new OpDefLibrary(); | ||||
| public static Tensor _all(Tensor input, Tensor axis, bool keep_dims = false, string name = null) | |||||
| { | |||||
| var _op = _op_def_lib._apply_op_helper("All", name, args: new { input, reduction_indices = axis, keep_dims = keep_dims }); | |||||
| return _op.outputs[0]; | |||||
| } | |||||
| /// <summary> | /// <summary> | ||||
| /// Returns the index with the largest value across dimensions of a tensor. | /// Returns the index with the largest value across dimensions of a tensor. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -250,7 +257,7 @@ namespace Tensorflow | |||||
| /// <param name="y"></param> | /// <param name="y"></param> | ||||
| /// <param name="name"></param> | /// <param name="name"></param> | ||||
| /// <returns></returns> | /// <returns></returns> | ||||
| public static Tensor equal(Tensor x, Tensor y, string name = null) | |||||
| public static Tensor equal<Tx, Ty>(Tx x, Ty y, string name = null) | |||||
| { | { | ||||
| var _op = _op_def_lib._apply_op_helper("Equal", name, args: new { x, y }); | var _op = _op_def_lib._apply_op_helper("Equal", name, args: new { x, y }); | ||||
| @@ -37,6 +37,27 @@ namespace Tensorflow | |||||
| }); | }); | ||||
| } | } | ||||
| /// <summary> | |||||
| /// Adds all input tensors element-wise. | |||||
| /// </summary> | |||||
| /// <param name="inputs"></param> | |||||
| /// <param name="name"></param> | |||||
| /// <returns></returns> | |||||
| public static Tensor add_n(Tensor[] inputs, string name = null) | |||||
| { | |||||
| inputs = ops.convert_n_to_tensor_or_indexed_slices(inputs); | |||||
| if(inputs.Length == 1) | |||||
| { | |||||
| var values = inputs[0]; | |||||
| if (name != null) | |||||
| return array_ops.identity(values, name: name); | |||||
| return values; | |||||
| } | |||||
| throw new NotImplementedException("math_ops add_n n > 1"); | |||||
| // return gen_math_ops.add_n(inputs, name: name); | |||||
| } | |||||
| public static Tensor cast(Tensor x, TF_DataType dtype = TF_DataType.DtInvalid, string name = null) | public static Tensor cast(Tensor x, TF_DataType dtype = TF_DataType.DtInvalid, string name = null) | ||||
| { | { | ||||
| var base_type = dtype.as_base_dtype(); | var base_type = dtype.as_base_dtype(); | ||||
| @@ -161,7 +182,24 @@ namespace Tensorflow | |||||
| /// <returns></returns> | /// <returns></returns> | ||||
| public static Tensor reciprocal(Tensor x, string name = null) | public static Tensor reciprocal(Tensor x, string name = null) | ||||
| => gen_math_ops.reciprocal(x, name: name); | => gen_math_ops.reciprocal(x, name: name); | ||||
| /// <summary> | |||||
| /// Computes the "logical and" of elements across dimensions of a tensor. | |||||
| /// </summary> | |||||
| /// <param name="input_tensor"></param> | |||||
| /// <param name="axis"></param> | |||||
| /// <param name="keepdims"></param> | |||||
| /// <param name="name"></param> | |||||
| /// <returns></returns> | |||||
| public static Tensor reduce_all(Tensor input_tensor, int[] axis = null, bool keepdims = false, string name = null) | |||||
| { | |||||
| var all = gen_math_ops._all(input_tensor, | |||||
| _ReductionDims(input_tensor, axis), | |||||
| keepdims, | |||||
| name: name); | |||||
| return _may_reduce_to_scalar(keepdims, axis, all); | |||||
| } | |||||
| /// <summary> | /// <summary> | ||||
| /// Computes log(sum(exp(elements across dimensions of a tensor))). | /// Computes log(sum(exp(elements across dimensions of a tensor))). | ||||
| @@ -346,20 +346,17 @@ namespace Tensorflow | |||||
| session.run(operation, feed_dict); | session.run(operation, feed_dict); | ||||
| } | } | ||||
| public static Tensor[] convert_n_to_tensor(object[] values, TF_DataType dtype = TF_DataType.DtInvalid, string name = null) | |||||
| => internal_convert_n_to_tensor(values, dtype: dtype, name: name, as_ref: false); | |||||
| public static Tensor[] convert_n_to_tensor_or_indexed_slices(Tensor[] values, TF_DataType dtype = TF_DataType.DtInvalid, string name = null) | public static Tensor[] convert_n_to_tensor_or_indexed_slices(Tensor[] values, TF_DataType dtype = TF_DataType.DtInvalid, string name = null) | ||||
| { | |||||
| return internal_convert_n_to_tensor_or_indexed_slices(values, dtype: dtype, name: name); | |||||
| } | |||||
| => internal_convert_n_to_tensor_or_indexed_slices(values, dtype: dtype, name: name); | |||||
| public static Tensor convert_to_tensor_or_indexed_slices(Tensor value, TF_DataType dtype = TF_DataType.DtInvalid, string name = null) | public static Tensor convert_to_tensor_or_indexed_slices(Tensor value, TF_DataType dtype = TF_DataType.DtInvalid, string name = null) | ||||
| { | |||||
| return internal_convert_to_tensor_or_indexed_slices(value: value, dtype: dtype, name: name, as_ref: false); | |||||
| } | |||||
| => internal_convert_to_tensor_or_indexed_slices(value: value, dtype: dtype, name: name, as_ref: false); | |||||
| public static Tensor internal_convert_to_tensor_or_indexed_slices(Tensor value, TF_DataType dtype = TF_DataType.DtInvalid, string name = null, bool as_ref = false) | public static Tensor internal_convert_to_tensor_or_indexed_slices(Tensor value, TF_DataType dtype = TF_DataType.DtInvalid, string name = null, bool as_ref = false) | ||||
| { | |||||
| return value; | |||||
| } | |||||
| => value; | |||||
| public static Tensor[] internal_convert_n_to_tensor_or_indexed_slices(Tensor[] values, TF_DataType dtype = TF_DataType.DtInvalid, string name = null, bool as_ref = false) | public static Tensor[] internal_convert_n_to_tensor_or_indexed_slices(Tensor[] values, TF_DataType dtype = TF_DataType.DtInvalid, string name = null, bool as_ref = false) | ||||
| { | { | ||||
| @@ -39,7 +39,7 @@ namespace TensorFlowNET.Examples | |||||
| // Build KMeans graph | // Build KMeans graph | ||||
| var training_graph = kmeans.training_graph(); | var training_graph = kmeans.training_graph(); | ||||
| return false; | return false; | ||||
| } | } | ||||