Skip to content

Commit 8c5ac3a

Browse files
committed
control_flow_ops.Asset.
gen_math_ops._all. math_ops.add_n.
1 parent a1853a9 commit 8c5ac3a

9 files changed

Lines changed: 199 additions & 13 deletions

File tree

src/TensorFlowNET.Core/Clustering/KMeans.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,17 @@ public object training_graph()
5353
var initial_clusters = _initial_clusters;
5454
var num_clusters = ops.convert_to_tensor(_num_clusters);
5555
var inputs = _inputs;
56-
_create_variables(num_clusters);
56+
var vars = _create_variables(num_clusters);
57+
var cluster_centers_var = vars[0];
58+
var cluster_centers_initialized = vars[1];
59+
var total_counts = vars[2];
60+
var cluster_centers_updated = vars[3];
61+
var update_in_steps = vars[4];
62+
63+
var init_op = new _InitializeClustersOpFactory(_inputs, num_clusters, initial_clusters, _distance_metric,
64+
_random_seed, _kmeans_plus_plus_num_retries,
65+
_kmc2_chain_length, cluster_centers_var, cluster_centers_updated,
66+
cluster_centers_initialized).op();
5767

5868
throw new NotImplementedException("KMeans training_graph");
5969
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
namespace Tensorflow.Clustering
7+
{
8+
/// <summary>
9+
/// Internal class to create the op to initialize the clusters.
10+
/// </summary>
11+
public class _InitializeClustersOpFactory
12+
{
13+
Tensor[] _inputs;
14+
Tensor _num_clusters;
15+
IInitializer _initial_clusters;
16+
string _distance_metric;
17+
int _random_seed;
18+
int _kmeans_plus_plus_num_retries;
19+
int _kmc2_chain_length;
20+
RefVariable _cluster_centers;
21+
RefVariable _cluster_centers_updated;
22+
RefVariable _cluster_centers_initialized;
23+
Tensor _num_selected;
24+
Tensor _num_remaining;
25+
Tensor _num_data;
26+
27+
public _InitializeClustersOpFactory(Tensor[] inputs,
28+
Tensor num_clusters,
29+
IInitializer initial_clusters,
30+
string distance_metric,
31+
int random_seed,
32+
int kmeans_plus_plus_num_retries,
33+
int kmc2_chain_length,
34+
RefVariable cluster_centers,
35+
RefVariable cluster_centers_updated,
36+
RefVariable cluster_centers_initialized)
37+
{
38+
_inputs = inputs;
39+
_num_clusters = num_clusters;
40+
_initial_clusters = initial_clusters;
41+
_distance_metric = distance_metric;
42+
_random_seed = random_seed;
43+
_kmeans_plus_plus_num_retries = kmeans_plus_plus_num_retries;
44+
_kmc2_chain_length = kmc2_chain_length;
45+
_cluster_centers = cluster_centers;
46+
_cluster_centers_updated = cluster_centers_updated;
47+
_cluster_centers_initialized = cluster_centers_initialized;
48+
49+
_num_selected = array_ops.shape(_cluster_centers)[0];
50+
_num_remaining = _num_clusters - _num_selected;
51+
52+
_num_data = math_ops.add_n(_inputs.Select(i => array_ops.shape(i)[0]).ToArray());
53+
}
54+
55+
public Tensor[] op()
56+
{
57+
return control_flow_ops.cond(gen_math_ops.equal(_num_remaining, 0),
58+
() => new Operation[] { check_ops.assert_equal(_cluster_centers_initialized, true) },
59+
() => new Operation[0]);
60+
}
61+
}
62+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace Tensorflow
6+
{
7+
public class check_ops : Python
8+
{
9+
/// <summary>
10+
/// Assert the condition `x == y` holds element-wise.
11+
/// </summary>
12+
/// <param name="t1"></param>
13+
/// <param name="t2"></param>
14+
/// <param name="name"></param>
15+
public static Operation assert_equal(object t1, object t2, object[] data = null, string name = null)
16+
{
17+
return with(ops.name_scope(name, "assert_equal", new { t1, t2, data }), delegate
18+
{
19+
var x = ops.convert_to_tensor(t1, name: "x");
20+
var y = ops.convert_to_tensor(t2, name: "y");
21+
var condition = math_ops.reduce_all(gen_math_ops.equal(x, y));
22+
var x_static = tensor_util.constant_value(x);
23+
var y_static = tensor_util.constant_value(y);
24+
return control_flow_ops.Asset(condition, data);
25+
});
26+
}
27+
}
28+
}

src/TensorFlowNET.Core/Operations/control_flow_ops.py.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,29 @@ namespace Tensorflow
99
{
1010
public class control_flow_ops : Python
1111
{
12+
public static Operation Asset(Tensor condition, object[] data, int? summarize = null, string name = null)
13+
{
14+
return with(ops.name_scope(name, "Assert", new { condition, data }), scope =>
15+
{
16+
name = scope;
17+
var xs = ops.convert_n_to_tensor(data);
18+
condition = ops.convert_to_tensor(condition, name: "Condition");
19+
Func<Operation[]> true_assert = () => new Operation[]
20+
{
21+
gen_logging_ops._assert(condition, data, summarize, name: "Assert")
22+
};
23+
24+
Func<Operation[]> false_assert = () => new Operation[]
25+
{
26+
gen_control_flow_ops.no_op()
27+
};
28+
29+
var guarded_assert = cond(condition, false_assert, true_assert, name: "AssertGuard");
30+
31+
return guarded_assert[0].op;
32+
});
33+
}
34+
1235
public static Operation group<T>(T[] inputs, string name = null) where T : ITensorOrOperation
1336
{
1437
return with(ops.name_scope(name, "group_deps", inputs), scope =>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace Tensorflow
6+
{
7+
public class gen_logging_ops
8+
{
9+
public static OpDefLibrary _op_def_lib = new OpDefLibrary();
10+
11+
public static Operation _assert(Tensor condition, object[] data, int? summarize = 3, string name = null)
12+
{
13+
if (!summarize.HasValue)
14+
summarize = 3;
15+
16+
var _op = _op_def_lib._apply_op_helper("Assert", name, args: new { condition, data, summarize });
17+
18+
return _op;
19+
}
20+
}
21+
}

src/TensorFlowNET.Core/Operations/gen_math_ops.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ public static class gen_math_ops
1010
{
1111
public static OpDefLibrary _op_def_lib = new OpDefLibrary();
1212

13+
public static Tensor _all(Tensor input, Tensor axis, bool keep_dims = false, string name = null)
14+
{
15+
var _op = _op_def_lib._apply_op_helper("All", name, args: new { input, reduction_indices = axis, keep_dims = keep_dims });
16+
17+
return _op.outputs[0];
18+
}
19+
1320
/// <summary>
1421
/// Returns the index with the largest value across dimensions of a tensor.
1522
/// </summary>
@@ -250,7 +257,7 @@ public static Tensor sub<Tx, Ty>(Tx x, Ty y, string name = null)
250257
/// <param name="y"></param>
251258
/// <param name="name"></param>
252259
/// <returns></returns>
253-
public static Tensor equal(Tensor x, Tensor y, string name = null)
260+
public static Tensor equal<Tx, Ty>(Tx x, Ty y, string name = null)
254261
{
255262
var _op = _op_def_lib._apply_op_helper("Equal", name, args: new { x, y });
256263

src/TensorFlowNET.Core/Operations/math_ops.cs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,27 @@ public static Tensor add(Tensor x, string name = null)
3737
});
3838
}
3939

40+
/// <summary>
41+
/// Adds all input tensors element-wise.
42+
/// </summary>
43+
/// <param name="inputs"></param>
44+
/// <param name="name"></param>
45+
/// <returns></returns>
46+
public static Tensor add_n(Tensor[] inputs, string name = null)
47+
{
48+
inputs = ops.convert_n_to_tensor_or_indexed_slices(inputs);
49+
50+
if(inputs.Length == 1)
51+
{
52+
var values = inputs[0];
53+
if (name != null)
54+
return array_ops.identity(values, name: name);
55+
return values;
56+
}
57+
throw new NotImplementedException("math_ops add_n n > 1");
58+
// return gen_math_ops.add_n(inputs, name: name);
59+
}
60+
4061
public static Tensor cast(Tensor x, TF_DataType dtype = TF_DataType.DtInvalid, string name = null)
4162
{
4263
var base_type = dtype.as_base_dtype();
@@ -161,7 +182,24 @@ public static Tensor reduced_shape(Tensor input_shape, Tensor axes)
161182
/// <returns></returns>
162183
public static Tensor reciprocal(Tensor x, string name = null)
163184
=> gen_math_ops.reciprocal(x, name: name);
164-
185+
186+
/// <summary>
187+
/// Computes the "logical and" of elements across dimensions of a tensor.
188+
/// </summary>
189+
/// <param name="input_tensor"></param>
190+
/// <param name="axis"></param>
191+
/// <param name="keepdims"></param>
192+
/// <param name="name"></param>
193+
/// <returns></returns>
194+
public static Tensor reduce_all(Tensor input_tensor, int[] axis = null, bool keepdims = false, string name = null)
195+
{
196+
var all = gen_math_ops._all(input_tensor,
197+
_ReductionDims(input_tensor, axis),
198+
keepdims,
199+
name: name);
200+
201+
return _may_reduce_to_scalar(keepdims, axis, all);
202+
}
165203

166204
/// <summary>
167205
/// Computes log(sum(exp(elements across dimensions of a tensor))).

src/TensorFlowNET.Core/ops.py.cs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -346,20 +346,17 @@ public static void _run_using_default_session(Operation operation, FeedItem[] fe
346346
session.run(operation, feed_dict);
347347
}
348348

349+
public static Tensor[] convert_n_to_tensor(object[] values, TF_DataType dtype = TF_DataType.DtInvalid, string name = null)
350+
=> internal_convert_n_to_tensor(values, dtype: dtype, name: name, as_ref: false);
351+
349352
public static Tensor[] convert_n_to_tensor_or_indexed_slices(Tensor[] values, TF_DataType dtype = TF_DataType.DtInvalid, string name = null)
350-
{
351-
return internal_convert_n_to_tensor_or_indexed_slices(values, dtype: dtype, name: name);
352-
}
353+
=> internal_convert_n_to_tensor_or_indexed_slices(values, dtype: dtype, name: name);
353354

354355
public static Tensor convert_to_tensor_or_indexed_slices(Tensor value, TF_DataType dtype = TF_DataType.DtInvalid, string name = null)
355-
{
356-
return internal_convert_to_tensor_or_indexed_slices(value: value, dtype: dtype, name: name, as_ref: false);
357-
}
356+
=> internal_convert_to_tensor_or_indexed_slices(value: value, dtype: dtype, name: name, as_ref: false);
358357

359358
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)
360-
{
361-
return value;
362-
}
359+
=> value;
363360

364361
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)
365362
{

test/TensorFlowNET.Examples/KMeansClustering.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public bool Run()
3939

4040
// Build KMeans graph
4141
var training_graph = kmeans.training_graph();
42-
42+
4343
return false;
4444
}
4545

0 commit comments

Comments
 (0)