diff --git a/src/TensorFlowNET.Core/APIs/tf.image.cs b/src/TensorFlowNET.Core/APIs/tf.image.cs index 34cb4be7..b2db6b41 100644 --- a/src/TensorFlowNET.Core/APIs/tf.image.cs +++ b/src/TensorFlowNET.Core/APIs/tf.image.cs @@ -60,7 +60,11 @@ namespace Tensorflow public Tensor resize_images_v2(Tensor images, TensorShape size, string method = ResizeMethod.BILINEAR, bool preserve_aspect_ratio = false, bool antialias = false, string name = null) - => image_ops_impl.resize_images(images, tf.constant(size.dims), method, preserve_aspect_ratio, antialias, name); + => image_ops_impl.resize_images_v2(images, size, method, preserve_aspect_ratio, antialias, name); + + public Tensor resize_images_v2(Tensor images, Tensor size, string method = ResizeMethod.BILINEAR, bool preserve_aspect_ratio = false, bool antialias = false, + string name = null) + => image_ops_impl.resize_images_v2(images, size, method, preserve_aspect_ratio, antialias, name); public Tensor resize_images_with_pad(Tensor image, int target_height, int target_width, string method, bool antialias) => image_ops_impl.resize_images_with_pad(image, target_height, target_width, method, antialias); @@ -209,6 +213,9 @@ namespace Tensorflow public Tensor resize(Tensor image, TensorShape size, string method = ResizeMethod.BILINEAR) => image_ops_impl.resize_images_v2(image, size, method: method); + public Tensor resize(Tensor image, Tensor size, string method = ResizeMethod.BILINEAR) + => image_ops_impl.resize_images_v2(image, size, method: method); + public Tensor resize_bilinear(Tensor images, Tensor size, bool align_corners = false, bool half_pixel_centers = false, string name = null) => gen_image_ops.resize_bilinear(images, size, align_corners: align_corners, half_pixel_centers: half_pixel_centers, name: name); diff --git a/src/TensorFlowNET.Core/Operations/gen_array_ops.cs b/src/TensorFlowNET.Core/Operations/gen_array_ops.cs index 51f1c1c9..a5410185 100644 --- a/src/TensorFlowNET.Core/Operations/gen_array_ops.cs +++ b/src/TensorFlowNET.Core/Operations/gen_array_ops.cs @@ -175,11 +175,12 @@ namespace Tensorflow { if (tf.Context.executing_eagerly()) { - var results = tf.Runner.TFE_FastPathExecute(tf.Context, tf.Context.DeviceName, + /*var results = tf.Runner.TFE_FastPathExecute(tf.Context, tf.Context.DeviceName, "Pad", name, null, input, paddings); - return results[0]; + return results[0];*/ + return pad_eager_fallback(input, paddings, name: name, ctx: tf.Context); } var _op = tf.OpDefLib._apply_op_helper("Pad", name: name, args: new { input, paddings }); @@ -187,6 +188,19 @@ namespace Tensorflow return _op.output; } + private static Tensor pad_eager_fallback(Tensor inputs, Tensor padding, string name = null, Context ctx = null) + { + var (_attr_T, input) = tf.Runner.ArgsToMatchingEager(ctx, args: new[] { inputs }); + var (_attr_Tpaddings, paddings) = tf.Runner.ArgsToMatchingEager(ctx, default_dtype: tf.int32, args: new[] { padding }); + var _inputs_flat = input.concat(paddings); + var _attrs = new object[] { "T", _attr_T, "Tpaddings", _attr_Tpaddings }; + + var results = tf.Runner.Execute(ctx, "Pad", 1, _inputs_flat, _attrs, name: name); + if (tf.Runner.MustRecordGradient()) + tf.Runner.RecordGradient("Pad", _inputs_flat, _attrs, results); + return results[0]; + } + public static Tensor pack(Tensor[] values, int axis = 0, string name = null) { if (tf.Context.executing_eagerly()) diff --git a/src/TensorFlowNET.Core/Operations/image_ops_impl.cs b/src/TensorFlowNET.Core/Operations/image_ops_impl.cs index 836e1862..014e376a 100644 --- a/src/TensorFlowNET.Core/Operations/image_ops_impl.cs +++ b/src/TensorFlowNET.Core/Operations/image_ops_impl.cs @@ -2210,7 +2210,7 @@ new_height, new_width"); /// /// /// - public static Tensor resize_images_v2(Tensor images, TensorShape size, string method = ResizeMethod.BILINEAR, + public static Tensor resize_images_v2(Tensor images, T size, string method = ResizeMethod.BILINEAR, bool preserve_aspect_ratio = false, bool antialias = false, string name = null) diff --git a/src/TensorFlowNET.Keras/BackendImpl.cs b/src/TensorFlowNET.Keras/BackendImpl.cs index 8454c9bf..39557173 100644 --- a/src/TensorFlowNET.Keras/BackendImpl.cs +++ b/src/TensorFlowNET.Keras/BackendImpl.cs @@ -183,5 +183,48 @@ namespace Tensorflow.Keras throw new NotImplementedException(""); } + + /// + /// Resizes the images contained in a 4D tensor. + /// + /// + /// + /// + /// + /// + /// + public Tensor resize_images(Tensor x, int height_factor, int width_factor, + string data_format, string interpolation = "nearest") + { + var (rows, cols) = (0, 0); + if (data_format == "channels_first") + (rows, cols) = (2, 3); + else if (data_format == "channels_last") + (rows, cols) = (1, 2); + else + throw new ValueError($"Invalid `data_format` argument: {data_format}"); + + var original_shape = x.shape; + var new_shape = array_ops.shape(x)[new Slice(rows, cols + 1)]; + new_shape *= constant_op.constant(np.array(height_factor, width_factor)); + + if (data_format == "channels_first") + // x = permute_dimensions(x, [0, 2, 3, 1]); + throw new NotImplementedException(""); + if (interpolation == "nearest") + x = tf.image.resize_images_v2(x, new_shape, method: ResizeMethod.NEAREST_NEIGHBOR); + + if (data_format == "channels_first") + // x = permute_dimensions(x, [0, 3, 1, 2]); + throw new NotImplementedException(""); + + int new_height = original_shape[rows] < 0 ? -1 : original_shape[rows] * height_factor; + int new_width = original_shape[cols] < 0 ? -1 : original_shape[cols] * width_factor; + + TensorShape output_shape = data_format == "channels_first" ? + (-1, -1, new_height, new_width) : (-1, new_height, new_width, -1); + x.set_shape(output_shape); + return x; + } } }