Skip to content

Commit db7aac2

Browse files
committed
Add CategoricalCrossentropy.
1 parent 59106f8 commit db7aac2

25 files changed

+197
-93
lines changed

src/TensorFlowNET.Core/APIs/tf.nn.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,16 +126,18 @@ public Tensor relu(Tensor features, string name = null)
126126
public Tensor[] fused_batch_norm(Tensor x,
127127
IVariableV1 scale,
128128
IVariableV1 offset,
129-
Tensor mean = null,
130-
Tensor variance = null,
129+
IVariableV1 mean = null,
130+
IVariableV1 variance = null,
131131
float epsilon = 0.001f,
132132
string data_format = "NHWC",
133133
bool is_training = true,
134-
string name = null) => nn_impl.fused_batch_norm(x, scale, offset, mean, variance,
134+
string name = null,
135+
float exponential_avg_factor = 1.0f) => nn_impl.fused_batch_norm(x, scale, offset, mean, variance,
135136
epsilon: epsilon,
136137
data_format: data_format,
137138
is_training: is_training,
138-
name: name);
139+
name: name,
140+
exponential_avg_factor: exponential_avg_factor);
139141

140142
public Tensor max_pool(Tensor value, int[] ksize, int[] strides, string padding, string data_format = "NHWC", string name = null)
141143
=> nn_ops.max_pool(value, ksize, strides, padding, data_format: data_format, name: name);

src/TensorFlowNET.Core/Binding.Util.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ public static void tf_with(ITensorFlowObject py, Action<ITensorFlowObject> actio
180180
}
181181
}
182182

183-
// [DebuggerStepThrough]
183+
[DebuggerStepThrough]
184184
public static void tf_with<T>(T py, Action<T> action) where T : ITensorFlowObject
185185
{
186186
try

src/TensorFlowNET.Core/Contexts/Context.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public void restore_mode()
9191
}
9292

9393
[DebuggerStepThrough]
94-
public Tensor RunInAutoMode(Func<Tensor> graphAction, Func<Tensor> eagerAction, params Tensor[] tensors)
94+
public T RunInAutoMode<T>(Func<T> graphAction, Func<T> eagerAction, params Tensor[] tensors)
9595
{
9696
var shouldRunInEager = executing_eagerly()
9797
&& tensors.Count(x => x.IsEagerTensor) == tensors.Length;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System;
2+
using Tensorflow.Gradients;
3+
using static Tensorflow.Binding;
4+
using static Tensorflow.tensorflow;
5+
6+
namespace Tensorflow.Eager
7+
{
8+
public partial class EagerRunner
9+
{
10+
public bool MustRecordGradient()
11+
{
12+
return HasGradientTape();
13+
}
14+
}
15+
}

src/TensorFlowNET.Core/Eager/IEagerRunner.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,7 @@ bool RecordGradient(string op_name,
3838
Tensor[] inputs,
3939
object[] attrs,
4040
Tensor[] results);
41+
42+
bool MustRecordGradient();
4143
}
4244
}

src/TensorFlowNET.Core/Framework/smart_module.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public static Tensor smart_cond(bool pred,
5252
{
5353
var pred_value = tensor_util.constant_value(pred);
5454
if (pred_value is null)
55-
return null;
55+
return pred.eval(new Session(pred.graph));
5656

5757
return pred_value;
5858
}

src/TensorFlowNET.Core/Operations/NnOps/gen_nn_ops.cs

Lines changed: 47 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -269,21 +269,29 @@ public static Tensor[] fused_batch_norm_grad(FusedBatchNormParams @params)
269269
}
270270

271271
public static Tensor[] fused_batch_norm_grad_v3(FusedBatchNormParams @params)
272-
{
273-
var op = tf.OpDefLib._apply_op_helper("FusedBatchNormGradV3", name: @params.Name, args: new
274-
{
275-
y_backprop = @params.YBackprop,
276-
x = @params.X,
277-
scale = @params.Scale,
278-
reserve_space_1 = @params.ReserveSpace1,
279-
reserve_space_2 = @params.ReserveSpace2,
280-
reserve_space_3 = @params.ReserveSpace3,
281-
epsilon = @params.Epsilon,
282-
data_format = @params.DataFormat,
283-
is_training = @params.IsTraining
284-
});
285-
return op.outputs;
286-
}
272+
=> tf.Context.RunInAutoMode(()
273+
=> tf.OpDefLib._apply_op_helper("FusedBatchNormGradV3", name: @params.Name,
274+
args: new
275+
{
276+
y_backprop = @params.YBackprop,
277+
x = @params.X,
278+
scale = @params.Scale,
279+
reserve_space_1 = @params.ReserveSpace1,
280+
reserve_space_2 = @params.ReserveSpace2,
281+
reserve_space_3 = @params.ReserveSpace3,
282+
epsilon = @params.Epsilon,
283+
data_format = @params.DataFormat,
284+
is_training = @params.IsTraining
285+
}).outputs, ()
286+
=> tf.Runner.TFE_FastPathExecute(tf.Context, tf.Context.DeviceName,
287+
"FusedBatchNormGradV3", @params.Name,
288+
null,
289+
@params.YBackprop, @params.X, @params.Scale,
290+
@params.ReserveSpace1, @params.ReserveSpace2, @params.ReserveSpace3,
291+
"epsilon", @params.Epsilon,
292+
"data_format", @params.DataFormat,
293+
"is_training", @params.IsTraining),
294+
@params.YBackprop);
287295

288296
public static Tensor[] fused_batch_norm(Tensor x,
289297
Tensor scale,
@@ -313,9 +321,10 @@ public static Tensor[] fused_batch_norm(Tensor x,
313321
public static Tensor[] fused_batch_norm_v3(Tensor x,
314322
Tensor scale,
315323
Tensor offset,
316-
Tensor mean,
317-
Tensor variance,
324+
IVariableV1 mean,
325+
IVariableV1 variance,
318326
float epsilon = 0.0001f,
327+
float exponential_avg_factor = 1.0f,
319328
string data_format = "NHWC",
320329
bool is_training = true,
321330
string name = null)
@@ -328,9 +337,10 @@ public static Tensor[] fused_batch_norm_v3(Tensor x,
328337
x,
329338
scale,
330339
offset,
331-
mean,
332-
variance,
340+
mean.AsTensor(),
341+
variance.AsTensor(),
333342
"epsilon", epsilon,
343+
"exponential_avg_factor", exponential_avg_factor,
334344
"data_format", data_format,
335345
"is_training", is_training);
336346

@@ -378,14 +388,14 @@ public static Tensor local_response_normalization(Tensor input, int depth_radius
378388
}
379389

380390
public static Tensor log_softmax(Tensor logits, string name = null)
381-
{
382-
var _op = tf.OpDefLib._apply_op_helper("LogSoftmax", name: name, args: new
383-
{
384-
logits
385-
});
386-
387-
return _op.output;
388-
}
391+
=> tf.Context.RunInAutoMode(()
392+
=> tf.OpDefLib._apply_op_helper("LogSoftmax", name: name,
393+
args: new { logits }).output, ()
394+
=> tf.Runner.TFE_FastPathExecute(tf.Context, tf.Context.DeviceName,
395+
"LogSoftmax", name,
396+
null,
397+
logits).FirstOrDefault(),
398+
logits);
389399

390400
/// <summary>
391401
/// Says whether the targets are in the top `K` predictions.
@@ -560,6 +570,16 @@ public static Tensor softmax(Tensor logits, string name = null)
560570
/// <returns></returns>
561571
public static (Tensor, Tensor) softmax_cross_entropy_with_logits(Tensor features, Tensor labels, string name = null)
562572
{
573+
if (tf.executing_eagerly())
574+
{
575+
var results = tf.Runner.TFE_FastPathExecute(tf.Context, tf.Context.DeviceName,
576+
"SoftmaxCrossEntropyWithLogits", name,
577+
null,
578+
features, labels);
579+
580+
return (results[0], results[1]);
581+
}
582+
563583
var _op = tf.OpDefLib._apply_op_helper("SoftmaxCrossEntropyWithLogits", name: name, args: new
564584
{
565585
features,

src/TensorFlowNET.Core/Operations/gen_resource_variable_ops.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public static Operation assign_variable_op(Tensor resource, Tensor value, string
6868
null,
6969
resource, value);
7070

71-
return null;
71+
return results.Length == 0 ? null : results[0];
7272
}
7373

7474
var _op = tf.OpDefLib._apply_op_helper("AssignVariableOp", name, new { resource, value });

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

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -99,20 +99,21 @@ public static (Tensor, Tensor) moments(Tensor x,
9999
public static Tensor[] fused_batch_norm(Tensor x,
100100
IVariableV1 scale,
101101
IVariableV1 offset,
102-
Tensor mean,
103-
Tensor variance,
102+
IVariableV1 mean,
103+
IVariableV1 variance,
104104
float epsilon = 0.001f,
105105
string data_format = "NHWC",
106106
bool is_training = true,
107-
string name = null)
107+
string name = null,
108+
float exponential_avg_factor = 1.0f)
108109
{
109110
x = ops.convert_to_tensor(x, name: "input");
110111
var scale_tensor = ops.convert_to_tensor(scale, name: "scale");
111112
var offset_tensor = ops.convert_to_tensor(offset, name: "offset");
112-
if (mean == null)
113+
/*if (mean == null)
113114
mean = constant_op.constant(new float[0]);
114115
if (variance == null)
115-
variance = constant_op.constant(new float[0]);
116+
variance = constant_op.constant(new float[0]);*/
116117
var min_epsilon = 1.001e-5f;
117118
epsilon = epsilon > min_epsilon ? epsilon : min_epsilon;
118119

@@ -122,15 +123,16 @@ public static Tensor[] fused_batch_norm(Tensor x,
122123
mean,
123124
variance,
124125
epsilon,
125-
data_format,
126-
is_training,
127-
name);
126+
exponential_avg_factor: exponential_avg_factor,
127+
data_format: data_format,
128+
is_training: is_training,
129+
name: name);
128130

129131
var y = results[0];
130-
var batch_mean = results[1];
131-
var batch_var = results[2];
132+
var running_mean = results[1];
133+
var running_var = results[2];
132134

133-
return new[] { y, batch_mean, batch_var };
135+
return new[] { y, running_mean, running_var };
134136
}
135137

136138
/// <summary>

src/TensorFlowNET.Core/Operations/nn_ops.cs

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ public static Tensor softmax_cross_entropy_with_logits_v2_helper(Tensor labels,
255255

256256
// The output cost shape should be the input minus axis.
257257
var output_shape = array_ops.slice(input_shape,
258-
new int[] { 0 },
258+
new Tensor[] { constant_op.constant(0) },
259259
new Tensor[] { math_ops.subtract(input_rank, 1) });
260260

261261
cost = array_ops.reshape(cost, output_shape);
@@ -274,36 +274,38 @@ private static Tensor _flatten_outer_dims(Tensor logits)
274274
var rank = array_ops.rank(logits);
275275
var last_dim_size = array_ops.slice(array_ops.shape(logits),
276276
new[] { math_ops.subtract(rank, 1) },
277-
new[] { 1 });
277+
new[] { constant_op.constant(1) });
278278

279279
var ops = array_ops.concat(new[] { new[] { -1 }, (object)last_dim_size }, 0);
280280
var output = array_ops.reshape(logits, ops);
281281

282282
// Set output shape if known.
283-
// if not context.executing_eagerly():
284-
var shape = logits.TensorShape;
285-
if (shape != null && shape.ndim > 0)
283+
if (!tf.Context.executing_eagerly())
286284
{
287-
var product = 1;
288-
var product_valid = true;
289-
foreach (var d in shape.dims.Take(shape.ndim - 1))
285+
var shape = logits.TensorShape;
286+
if (shape != null && shape.ndim > 0)
290287
{
291-
if (d == -1)
288+
var product = 1;
289+
var product_valid = true;
290+
foreach (var d in shape.dims.Take(shape.ndim - 1))
292291
{
293-
product_valid = false;
294-
break;
292+
if (d == -1)
293+
{
294+
product_valid = false;
295+
break;
296+
}
297+
else
298+
{
299+
product *= d;
300+
}
295301
}
296-
else
302+
303+
if (product_valid)
297304
{
298-
product *= d;
305+
var output_shape = new[] { product };
306+
throw new NotImplementedException("_flatten_outer_dims product_valid");
299307
}
300308
}
301-
302-
if (product_valid)
303-
{
304-
var output_shape = new[] { product };
305-
throw new NotImplementedException("_flatten_outer_dims product_valid");
306-
}
307309
}
308310

309311
return output;

0 commit comments

Comments
 (0)