@@ -53,7 +53,17 @@ namespace Tensorflow.Clustering | |||
var initial_clusters = _initial_clusters; | |||
var num_clusters = ops.convert_to_tensor(_num_clusters); | |||
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"); | |||
} | |||
@@ -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 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 | |||
{ | |||
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 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> | |||
/// Returns the index with the largest value across dimensions of a tensor. | |||
/// </summary> | |||
@@ -250,7 +257,7 @@ namespace Tensorflow | |||
/// <param name="y"></param> | |||
/// <param name="name"></param> | |||
/// <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 }); | |||
@@ -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) | |||
{ | |||
var base_type = dtype.as_base_dtype(); | |||
@@ -161,7 +182,24 @@ namespace Tensorflow | |||
/// <returns></returns> | |||
public static Tensor reciprocal(Tensor x, string name = null) | |||
=> 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> | |||
/// Computes log(sum(exp(elements across dimensions of a tensor))). | |||
@@ -346,20 +346,17 @@ namespace Tensorflow | |||
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) | |||
{ | |||
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) | |||
{ | |||
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) | |||
{ | |||
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) | |||
{ | |||
@@ -39,7 +39,7 @@ namespace TensorFlowNET.Examples | |||
// Build KMeans graph | |||
var training_graph = kmeans.training_graph(); | |||
return false; | |||
} | |||