From 88c7ade8bda044f6791c2681e069e88dba29ca13 Mon Sep 17 00:00:00 2001 From: Oceania2018 Date: Sat, 19 Dec 2020 21:55:44 -0600 Subject: [PATCH] Fix datatype for slice. --- .../Gradients/array_grad.cs | 34 +++++---- .../Operations/OpDefLibrary.cs | 21 ++++-- .../Operations/Operation.cs | 21 +++--- .../Operations/array_ops.cs | 64 ++++++++++++++++- .../Operations/control_flow_ops.cs | 2 +- .../Operations/gen_array_ops.cs | 72 ++----------------- .../Operations/gen_image_ops.cs | 4 +- .../Operations/gen_logging_ops.cs | 2 +- 8 files changed, 116 insertions(+), 104 deletions(-) diff --git a/src/TensorFlowNET.Core/Gradients/array_grad.cs b/src/TensorFlowNET.Core/Gradients/array_grad.cs index 6422c546..8df7b970 100644 --- a/src/TensorFlowNET.Core/Gradients/array_grad.cs +++ b/src/TensorFlowNET.Core/Gradients/array_grad.cs @@ -293,20 +293,24 @@ namespace Tensorflow.Gradients var strides = op.inputs[3]; var x = array_ops.shape(op.inputs[0], out_type: begin.dtype); + var x_static = tensor_util.constant_value(x); + var begin_static = tensor_util.constant_value(begin); + var end_static = tensor_util.constant_value(end); + var strides_static = tensor_util.constant_value(strides); return new Tensor[] { - gen_array_ops.strided_slice_grad( - x, - begin, - end, - strides, + array_ops.strided_slice_grad( + x_static, + begin_static, + end_static, + strides_static, grad, - begin_mask: int.Parse(op.get_attr("begin_mask").ToString()), - end_mask: int.Parse(op.get_attr("end_mask").ToString()), - ellipsis_mask: int.Parse(op.get_attr("ellipsis_mask").ToString()), - new_axis_mask: int.Parse(op.get_attr("new_axis_mask").ToString()), - shrink_axis_mask: int.Parse(op.get_attr("shrink_axis_mask").ToString())), + begin_mask: op.get_attr("begin_mask"), + end_mask: op.get_attr("end_mask"), + ellipsis_mask: op.get_attr("ellipsis_mask"), + new_axis_mask: op.get_attr("new_axis_mask"), + shrink_axis_mask: op.get_attr("shrink_axis_mask")), null, null, null @@ -331,11 +335,11 @@ namespace Tensorflow.Gradients begin, end, strides, - begin_mask: (int)op.get_attr("begin_mask"), - end_mask: (int)op.get_attr("end_mask"), - ellipsis_mask: (int)op.get_attr("ellipsis_mask"), - new_axis_mask: (int)op.get_attr("new_axis_mask"), - shrink_axis_mask: (int)op.get_attr("shrink_axis_mask")) + begin_mask: op.get_attr("begin_mask"), + end_mask: op.get_attr("end_mask"), + ellipsis_mask: op.get_attr("ellipsis_mask"), + new_axis_mask: op.get_attr("new_axis_mask"), + shrink_axis_mask: op.get_attr("shrink_axis_mask")) }; } diff --git a/src/TensorFlowNET.Core/Operations/OpDefLibrary.cs b/src/TensorFlowNET.Core/Operations/OpDefLibrary.cs index c350ec7a..7032d1d6 100644 --- a/src/TensorFlowNET.Core/Operations/OpDefLibrary.cs +++ b/src/TensorFlowNET.Core/Operations/OpDefLibrary.cs @@ -276,12 +276,16 @@ namespace Tensorflow } else { - attrs[input_arg.NumberAttr] = (values as Tensor[]).Length; - inferred_from[input_arg.NumberAttr] = input_name; - var num_attr = op_def.Attr.First(x => x.Name == input_arg.NumberAttr); - if (num_attr.HasMinimum && (values as Tensor[]).Length < num_attr.Minimum) - throw new ValueError($"List argument '{input_name}' to '{op_type_name}' Op with length {(values as Tensor[]).Length} shorter " + - $"than minimum length {num_attr.Minimum}"); + if(values is Tensor[] tensors) + { + var num_attr = op_def.Attr.First(x => x.Name == input_arg.NumberAttr); + if (num_attr.HasMinimum && tensors.Length < num_attr.Minimum) + throw new ValueError($"List argument '{input_name}' to '{op_type_name}' Op with length {(values as Tensor[]).Length} shorter " + + $"than minimum length {num_attr.Minimum}"); + + attrs[input_arg.NumberAttr] = Convert.ToInt64(tensors.Length); + inferred_from[input_arg.NumberAttr] = input_name; + } } // All tensors must have the same base type. @@ -378,7 +382,10 @@ namespace Tensorflow attr_value.F = (float)value; break; case "int": - attr_value.I = (int)value; + if (value is long value_long) + attr_value.I = value_long; + else + attr_value.I = Convert.ToInt64(value); if (attr_def.HasMinimum && attr_value.I < attr_def.Minimum) throw new ValueError($"Attr '{attr_def.Name}' of '{op_def.Name}' Op passed {attr_value.I} less than minimum {attr_def.Minimum}."); break; diff --git a/src/TensorFlowNET.Core/Operations/Operation.cs b/src/TensorFlowNET.Core/Operations/Operation.cs index 01afd489..365dbb1e 100644 --- a/src/TensorFlowNET.Core/Operations/Operation.cs +++ b/src/TensorFlowNET.Core/Operations/Operation.cs @@ -242,16 +242,17 @@ namespace Tensorflow if (string.IsNullOrEmpty(oneof_value)) return null; - if (oneof_value == "list") - throw new NotImplementedException($"Unsupported field type in {x.ToString()}"); - - if (string.Equals("type", oneof_value, StringComparison.OrdinalIgnoreCase)) - return x.Type; - - object result = x.GetType().GetProperty(oneof_value).GetValue(x); - if (result is Google.Protobuf.ByteString byteString) - return byteString.ToStringUtf8(); - return result; + switch (oneof_value.ToLower()) + { + case "list": + throw new NotImplementedException($"Unsupported field type in {oneof_value}"); + case "type": + return x.Type; + case "s": + return x.S.ToStringUtf8(); + default: + return x.GetType().GetProperty(oneof_value).GetValue(x); + } } public TF_AttrMetadata GetAttributeMetadata(string attr_name, Status s) diff --git a/src/TensorFlowNET.Core/Operations/array_ops.cs b/src/TensorFlowNET.Core/Operations/array_ops.cs index 5c335b81..cd862df3 100644 --- a/src/TensorFlowNET.Core/Operations/array_ops.cs +++ b/src/TensorFlowNET.Core/Operations/array_ops.cs @@ -122,7 +122,7 @@ namespace Tensorflow case TF_DataType.TF_FLOAT: return _constant_if_small(0.0F, shape, dtype, name); case TF_DataType.TF_INT64: - return _constant_if_small(0l, shape, dtype, name); + return _constant_if_small(0L, shape, dtype, name); case TF_DataType.TF_INT32: return _constant_if_small(0, shape, dtype, name); case TF_DataType.TF_INT8: @@ -671,6 +671,68 @@ namespace Tensorflow return op; } + /// + /// Returns the gradient of `StridedSlice`. + /// + /// Since `StridedSlice` cuts out pieces of its `input` which is size + /// `shape`, its gradient will have the same shape (which is passed here + /// as `shape`). The gradient will be zero in any element that the slice + /// does not select. + /// + /// Must be one of the following types: `int32`, `int64`. + /// Must have the same type as `shape`. + /// Must have the same type as `shape`. + /// Must have the same type as `shape`. + /// A `Tensor`. + /// An optional `int`. Defaults to `0`. + /// An optional `int`. Defaults to `0`. + /// An optional `int`. Defaults to `0`. + /// An optional `int`. Defaults to `0`. + /// An optional `int`. Defaults to `0`. + /// A name for the operation (optional). + /// A `Tensor`. Has the same type as `dy`. + public static Tensor strided_slice_grad(Tensor shape, Tensor begin, Tensor end, Tensor strides, Tensor dy, + long begin_mask = 0, long end_mask = 0, long ellipsis_mask = 0, long new_axis_mask = 0, + long shrink_axis_mask = 0, string name = null) + => tf.Context.RunInAutoMode2( + () => tf.OpDefLib._apply_op_helper("StridedSliceGrad", name, new + { + shape, + begin, + end, + strides, + dy, + begin_mask, + end_mask, + ellipsis_mask, + new_axis_mask, + shrink_axis_mask + }).output, + () => tf.Runner.TFE_FastPathExecute(tf.Context, tf.Context.DeviceName, + "StridedSliceGrad", name, + null, + shape, begin, end, strides, dy, + "begin_mask", begin_mask, + "end_mask", end_mask, + "ellipsis_mask", ellipsis_mask, + "new_axis_mask", new_axis_mask, + "shrink_axis_mask", shrink_axis_mask).FirstOrDefault(), + (op) => + { + var attrs = new object[] + { + "T", op.get_attr("T"), + "Index", op.get_attr("Index"), + "begin_mask", op.get_attr("begin_mask"), + "end_mask", op.get_attr("end_mask"), + "ellipsis_mask", op.get_attr("ellipsis_mask"), + "new_axis_mask", op.get_attr("new_axis_mask"), + "shrink_axis_mask", op.get_attr("shrink_axis_mask") + }; + tf.Runner.RecordGradient("StridedSliceGrad", op.inputs, attrs, op.outputs); + }, + new Tensors(shape, begin, end, strides, dy)); + /// /// Removes dimensions of size 1 from the shape of a tensor. /// Given a tensor `input`, this operation returns a tensor of the same type with diff --git a/src/TensorFlowNET.Core/Operations/control_flow_ops.cs b/src/TensorFlowNET.Core/Operations/control_flow_ops.cs index 119c4b35..e038f900 100644 --- a/src/TensorFlowNET.Core/Operations/control_flow_ops.cs +++ b/src/TensorFlowNET.Core/Operations/control_flow_ops.cs @@ -65,7 +65,7 @@ namespace Tensorflow return gen_control_flow_ops.next_iteration(data, name: name); } - public static Operation Assert(Tensor condition, object[] data, int? summarize = null, string name = null) + public static Operation Assert(Tensor condition, object[] data, long? summarize = null, string name = null) { if (tf.executing_eagerly()) { diff --git a/src/TensorFlowNET.Core/Operations/gen_array_ops.cs b/src/TensorFlowNET.Core/Operations/gen_array_ops.cs index 019d19be..27a4e5da 100644 --- a/src/TensorFlowNET.Core/Operations/gen_array_ops.cs +++ b/src/TensorFlowNET.Core/Operations/gen_array_ops.cs @@ -578,11 +578,11 @@ namespace Tensorflow } public static Tensor strided_slice(Tensor input, Tensor begin, Tensor end, Tensor strides, - int begin_mask = 0, - int end_mask = 0, - int ellipsis_mask = 0, - int new_axis_mask = 0, - int shrink_axis_mask = 0, + long begin_mask = 0, + long end_mask = 0, + long ellipsis_mask = 0, + long new_axis_mask = 0, + long shrink_axis_mask = 0, string name = null) => tf.Context.RunInAutoMode(() => tf.OpDefLib._apply_op_helper("StridedSlice", name, new @@ -656,68 +656,6 @@ namespace Tensorflow return _op.outputs[0]; } - /// - /// Returns the gradient of `StridedSlice`. - /// - /// Since `StridedSlice` cuts out pieces of its `input` which is size - /// `shape`, its gradient will have the same shape (which is passed here - /// as `shape`). The gradient will be zero in any element that the slice - /// does not select. - /// - /// Must be one of the following types: `int32`, `int64`. - /// Must have the same type as `shape`. - /// Must have the same type as `shape`. - /// Must have the same type as `shape`. - /// A `Tensor`. - /// An optional `int`. Defaults to `0`. - /// An optional `int`. Defaults to `0`. - /// An optional `int`. Defaults to `0`. - /// An optional `int`. Defaults to `0`. - /// An optional `int`. Defaults to `0`. - /// A name for the operation (optional). - /// A `Tensor`. Has the same type as `dy`. - public static Tensor strided_slice_grad(Tensor shape, Tensor begin, Tensor end, Tensor strides, Tensor dy, - int begin_mask = 0, int end_mask = 0, int ellipsis_mask = 0, int new_axis_mask = 0, - int shrink_axis_mask = 0, string name = null) - => tf.Context.RunInAutoMode2( - () => tf.OpDefLib._apply_op_helper("StridedSliceGrad", name, new - { - shape, - begin, - end, - strides, - dy, - begin_mask, - end_mask, - ellipsis_mask, - new_axis_mask, - shrink_axis_mask - }).output, - () => tf.Runner.TFE_FastPathExecute(tf.Context, tf.Context.DeviceName, - "StridedSliceGrad", name, - null, - shape, begin, end, strides, dy, - "begin_mask", begin_mask, - "end_mask", end_mask, - "ellipsis_mask", ellipsis_mask, - "new_axis_mask", new_axis_mask, - "shrink_axis_mask", shrink_axis_mask).FirstOrDefault(), - (op) => - { - var attrs = new object[] - { - "T", op.get_attr("T"), - "Index", op.get_attr("Index"), - "begin_mask", op.get_attr("begin_mask"), - "end_mask", op.get_attr("end_mask"), - "ellipsis_mask", op.get_attr("ellipsis_mask"), - "new_axis_mask", op.get_attr("new_axis_mask"), - "shrink_axis_mask", op.get_attr("shrink_axis_mask") - }; - tf.Runner.RecordGradient("StridedSliceGrad", op.inputs, attrs, op.outputs); - }, - new Tensors(shape, begin, end, strides, dy)); - /// /// Removes dimensions of size 1 from the shape of a tensor. /// Given a tensor `input`, this operation returns a tensor of the same type with diff --git a/src/TensorFlowNET.Core/Operations/gen_image_ops.cs b/src/TensorFlowNET.Core/Operations/gen_image_ops.cs index eed9e572..21045d75 100644 --- a/src/TensorFlowNET.Core/Operations/gen_image_ops.cs +++ b/src/TensorFlowNET.Core/Operations/gen_image_ops.cs @@ -63,8 +63,8 @@ namespace Tensorflow } public static Tensor decode_jpeg(Tensor contents, - int channels = 0, - int ratio = 1, + long channels = 0, + long ratio = 1, bool fancy_upscaling = true, bool try_recover_truncated = false, float acceptable_fraction = 1, diff --git a/src/TensorFlowNET.Core/Operations/gen_logging_ops.cs b/src/TensorFlowNET.Core/Operations/gen_logging_ops.cs index e9a31442..5e75bbd1 100644 --- a/src/TensorFlowNET.Core/Operations/gen_logging_ops.cs +++ b/src/TensorFlowNET.Core/Operations/gen_logging_ops.cs @@ -21,7 +21,7 @@ namespace Tensorflow { public class gen_logging_ops { - public static Operation _assert(Tensor condition, object[] data, int? summarize = 3, string name = null) + public static Operation _assert(Tensor condition, object[] data, long? summarize = 3, string name = null) { if (!summarize.HasValue) summarize = 3;