From 29554f6d97df3b1538110178f9a4838f323f5532 Mon Sep 17 00:00:00 2001 From: Faisal Alsrheed <47912291+Faisal-Alsrheed@users.noreply.github.com> Date: Thu, 31 Aug 2023 12:10:02 +0000 Subject: [PATCH 1/5] Increase-tests-in-ops/operation_utils_test.py --- keras_core/ops/operation_utils_test.py | 127 +++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/keras_core/ops/operation_utils_test.py b/keras_core/ops/operation_utils_test.py index 06e194281..b399f7b1f 100644 --- a/keras_core/ops/operation_utils_test.py +++ b/keras_core/ops/operation_utils_test.py @@ -17,3 +17,130 @@ def test_get_source_inputs(self): def test_get_source_inputs_return_input_tensor(self): inputs = input_layer.Input(shape=(10,)) self.assertIs(operation_utils.get_source_inputs(inputs)[0], inputs) + + def test_compute_pooling_output_shape(self): + input_shape = (1, 4, 4, 1) + pool_size = (2, 2) + output_shape = operation_utils.compute_pooling_output_shape( + input_shape, pool_size + ) + expected_output_shape = (1, 2, 2, 1) + self.assertEqual(output_shape, expected_output_shape) + + def test_compute_pooling_output_shape_with_none(self): + input_shape = (None, 4, 4, 1) + pool_size = (2, 2) + output_shape = operation_utils.compute_pooling_output_shape( + input_shape, pool_size + ) + expected_output_shape = (None, 2, 2, 1) + self.assertEqual(output_shape, expected_output_shape) + + def test_compute_pooling_output_shape_valid_padding(self): + input_shape = (1, 4, 4, 1) + pool_size = (2, 2) + strides = (2, 2) + output_shape = operation_utils.compute_pooling_output_shape( + input_shape, pool_size, strides, padding="valid" + ) + self.assertEqual(output_shape, (1, 2, 2, 1)) + + def test_compute_pooling_output_shape_channels_last(self): + input_shape = (1, 4, 4, 3) + pool_size = (2, 2) + strides = (2, 2) + output_shape = operation_utils.compute_pooling_output_shape( + input_shape, + pool_size, + strides, + padding="valid", + data_format="channels_last", + ) + self.assertEqual(output_shape, (1, 2, 2, 3)) + + def test_compute_pooling_output_shape_same_padding_stride1(self): + input_shape = (1, 4, 4, 3) + pool_size = (2, 2) + strides = (1, 1) + output_shape = operation_utils.compute_pooling_output_shape( + input_shape, + pool_size, + strides, + padding="same", + data_format="channels_last", + ) + self.assertEqual(output_shape, (1, 4, 4, 3)) + + def test_compute_conv_output_shape(self): + input_shape = (1, 4, 4, 1) + kernel_size = (3, 3) + output_shape = operation_utils.compute_conv_output_shape( + input_shape, kernel_size + ) + expected_output_shape = (1, 2, 2, 1) + self.assertEqual(output_shape, expected_output_shape) + + def test_compute_conv_output_shape_with_none(self): + input_shape = (None, 4, 4, 1) + kernel_size = (3, 3) + filters = 1 + output_shape = operation_utils.compute_conv_output_shape( + input_shape, filters, kernel_size + ) + expected_output_shape = (None, 2, 2, 1) + self.assertEqual(output_shape, expected_output_shape) + + def test_compute_conv_output_shape_valid_padding(self): + input_shape = (1, 4, 4, 1) + kernel_size = (3, 3) + filters = 1 + strides = (2, 2) + output_shape = operation_utils.compute_conv_output_shape( + input_shape, filters, kernel_size, strides, padding="valid" + ) + self.assertEqual(output_shape, (1, 1, 1, 1)) + + def test_compute_conv_output_shape_channels_last(self): + input_shape = (1, 4, 4, 3) + kernel_size = (3, 3) + filters = 3 + strides = (2, 2) + output_shape = operation_utils.compute_conv_output_shape( + input_shape, + filters, + kernel_size, + strides, + padding="valid", + data_format="channels_last", + ) + self.assertEqual(output_shape, (1, 1, 1, 3)) + + def test_compute_conv_output_shape_same_padding_stride1(self): + input_shape = (1, 4, 4, 3) + kernel_size = (3, 3) + filters = 3 + strides = (1, 1) + output_shape = operation_utils.compute_conv_output_shape( + input_shape, + filters, + kernel_size, + strides, + padding="same", + data_format="channels_last", + ) + self.assertEqual(output_shape, (1, 4, 4, 3)) + + def test_compute_reshape_output_shape(self): + input_shape = (1, 4, 4, 1) + target_shape = (16, 1) + output_shape = operation_utils.compute_reshape_output_shape( + input_shape, target_shape + ) + self.assertEqual(output_shape, target_shape) + + def test_reduce_shape(self): + input_shape = (1, 4, 4, 1) + axes = [1, 2] + output_shape = operation_utils.reduce_shape(input_shape, axes) + expected_output_shape = (1, 1, 1, 1) + self.assertEqual(output_shape, expected_output_shape) From 5cc6dc464bb0c9296bb909acc2fc2655ef916448 Mon Sep 17 00:00:00 2001 From: Faisal Alsrheed <47912291+Faisal-Alsrheed@users.noreply.github.com> Date: Thu, 31 Aug 2023 12:44:19 +0000 Subject: [PATCH 2/5] Increase-tests-in-ops/operation_utils_test.py --- keras_core/ops/operation_utils_test.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/keras_core/ops/operation_utils_test.py b/keras_core/ops/operation_utils_test.py index b399f7b1f..af102e602 100644 --- a/keras_core/ops/operation_utils_test.py +++ b/keras_core/ops/operation_utils_test.py @@ -21,8 +21,9 @@ def test_get_source_inputs_return_input_tensor(self): def test_compute_pooling_output_shape(self): input_shape = (1, 4, 4, 1) pool_size = (2, 2) + strides = (2, 2) output_shape = operation_utils.compute_pooling_output_shape( - input_shape, pool_size + input_shape, pool_size, strides ) expected_output_shape = (1, 2, 2, 1) self.assertEqual(output_shape, expected_output_shape) @@ -30,8 +31,9 @@ def test_compute_pooling_output_shape(self): def test_compute_pooling_output_shape_with_none(self): input_shape = (None, 4, 4, 1) pool_size = (2, 2) + strides = (2, 2) output_shape = operation_utils.compute_pooling_output_shape( - input_shape, pool_size + input_shape, pool_size, strides ) expected_output_shape = (None, 2, 2, 1) self.assertEqual(output_shape, expected_output_shape) @@ -74,8 +76,9 @@ def test_compute_pooling_output_shape_same_padding_stride1(self): def test_compute_conv_output_shape(self): input_shape = (1, 4, 4, 1) kernel_size = (3, 3) + strides = (1, 1) output_shape = operation_utils.compute_conv_output_shape( - input_shape, kernel_size + input_shape, kernel_size, strides ) expected_output_shape = (1, 2, 2, 1) self.assertEqual(output_shape, expected_output_shape) @@ -84,8 +87,9 @@ def test_compute_conv_output_shape_with_none(self): input_shape = (None, 4, 4, 1) kernel_size = (3, 3) filters = 1 + strides = (1, 1) output_shape = operation_utils.compute_conv_output_shape( - input_shape, filters, kernel_size + input_shape, filters, kernel_size, strides ) expected_output_shape = (None, 2, 2, 1) self.assertEqual(output_shape, expected_output_shape) @@ -134,7 +138,7 @@ def test_compute_reshape_output_shape(self): input_shape = (1, 4, 4, 1) target_shape = (16, 1) output_shape = operation_utils.compute_reshape_output_shape( - input_shape, target_shape + input_shape, new_shape=target_shape ) self.assertEqual(output_shape, target_shape) From 5a532dfec5957de219370f10b3a79d7e6a7a6cd5 Mon Sep 17 00:00:00 2001 From: Faisal Alsrheed <47912291+Faisal-Alsrheed@users.noreply.github.com> Date: Thu, 31 Aug 2023 13:12:22 +0000 Subject: [PATCH 3/5] Fix: the shape reduction logic in `reduce_shape` --- keras_core/ops/operation_utils.py | 2 +- keras_core/ops/operation_utils_test.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/keras_core/ops/operation_utils.py b/keras_core/ops/operation_utils.py index 7a4d3a0ea..0fdc24803 100644 --- a/keras_core/ops/operation_utils.py +++ b/keras_core/ops/operation_utils.py @@ -222,7 +222,7 @@ def reduce_shape(shape, axis=None, keepdims=False): shape = list(shape) if axis is None: if keepdims: - output_shape = [1 for _ in range(shape)] + output_shape = [1 for _ in range(len(shape))] else: output_shape = [] return output_shape diff --git a/keras_core/ops/operation_utils_test.py b/keras_core/ops/operation_utils_test.py index af102e602..793c5b3e0 100644 --- a/keras_core/ops/operation_utils_test.py +++ b/keras_core/ops/operation_utils_test.py @@ -75,10 +75,11 @@ def test_compute_pooling_output_shape_same_padding_stride1(self): def test_compute_conv_output_shape(self): input_shape = (1, 4, 4, 1) + filters = 1 kernel_size = (3, 3) strides = (1, 1) output_shape = operation_utils.compute_conv_output_shape( - input_shape, kernel_size, strides + input_shape, filters, kernel_size, strides ) expected_output_shape = (1, 2, 2, 1) self.assertEqual(output_shape, expected_output_shape) @@ -138,7 +139,7 @@ def test_compute_reshape_output_shape(self): input_shape = (1, 4, 4, 1) target_shape = (16, 1) output_shape = operation_utils.compute_reshape_output_shape( - input_shape, new_shape=target_shape + input_shape, new_shape=target_shape, new_shape_arg_name="New shape" ) self.assertEqual(output_shape, target_shape) From 3b622474c7342fdd85ffd939a3d414a6779e5dc8 Mon Sep 17 00:00:00 2001 From: Faisal Alsrheed <47912291+Faisal-Alsrheed@users.noreply.github.com> Date: Thu, 31 Aug 2023 13:23:58 +0000 Subject: [PATCH 4/5] fix reduce_shape Function + add Tests --- keras_core/ops/operation_utils.py | 14 ++++---- keras_core/ops/operation_utils_test.py | 46 ++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/keras_core/ops/operation_utils.py b/keras_core/ops/operation_utils.py index 0fdc24803..bfac73ec4 100644 --- a/keras_core/ops/operation_utils.py +++ b/keras_core/ops/operation_utils.py @@ -222,20 +222,18 @@ def reduce_shape(shape, axis=None, keepdims=False): shape = list(shape) if axis is None: if keepdims: - output_shape = [1 for _ in range(len(shape))] + return tuple([1 for _ in shape]) else: - output_shape = [] - return output_shape + return tuple([]) if keepdims: for ax in axis: shape[ax] = 1 - return shape + return tuple(shape) else: - for ax in axis: - shape[ax] = -1 - output_shape = list(filter((-1).__ne__, shape)) - return output_shape + for ax in sorted(axis, reverse=True): + del shape[ax] + return tuple(shape) @keras_core_export("keras_core.utils.get_source_inputs") diff --git a/keras_core/ops/operation_utils_test.py b/keras_core/ops/operation_utils_test.py index 793c5b3e0..111520214 100644 --- a/keras_core/ops/operation_utils_test.py +++ b/keras_core/ops/operation_utils_test.py @@ -143,9 +143,51 @@ def test_compute_reshape_output_shape(self): ) self.assertEqual(output_shape, target_shape) - def test_reduce_shape(self): + def test_reduce_shape_no_axes_no_keepdims(self): + input_shape = (1, 4, 4, 1) + output_shape = operation_utils.reduce_shape(input_shape) + expected_output_shape = () + self.assertEqual(output_shape, expected_output_shape) + + def test_reduce_shape_no_axes_with_keepdims(self): + input_shape = (1, 4, 4, 1) + output_shape = operation_utils.reduce_shape(input_shape, keepdims=True) + expected_output_shape = (1, 1, 1, 1) + self.assertEqual(output_shape, expected_output_shape) + + def test_reduce_shape_single_axis_no_keepdims(self): + input_shape = (1, 4, 4, 1) + axes = [1] + output_shape = operation_utils.reduce_shape(input_shape, axes) + expected_output_shape = (1, 4, 1) + self.assertEqual(output_shape, expected_output_shape) + + def test_reduce_shape_single_axis_with_keepdims(self): + input_shape = (1, 4, 4, 1) + axes = [1] + output_shape = operation_utils.reduce_shape( + input_shape, axes, keepdims=True + ) + expected_output_shape = (1, 1, 4, 1) + self.assertEqual(output_shape, expected_output_shape) + + def test_reduce_shape_multiple_axes_no_keepdims(self): input_shape = (1, 4, 4, 1) axes = [1, 2] output_shape = operation_utils.reduce_shape(input_shape, axes) - expected_output_shape = (1, 1, 1, 1) + expected_output_shape = (1, 1) + self.assertEqual(output_shape, expected_output_shape) + + def test_reduce_shape_out_of_order_axes_no_keepdims(self): + input_shape = (1, 4, 4, 1) + axes = [2, 1] + output_shape = operation_utils.reduce_shape(input_shape, axes) + expected_output_shape = (1, 1) + self.assertEqual(output_shape, expected_output_shape) + + def test_reduce_shape_with_negative_axes(self): + input_shape = (1, 4, 4, 1) + axes = [-2, -3] + output_shape = operation_utils.reduce_shape(input_shape, axes) + expected_output_shape = (1, 1) self.assertEqual(output_shape, expected_output_shape) From 7f3b263f0b18bf74c265990f3c51b106531fba79 Mon Sep 17 00:00:00 2001 From: Faisal Alsrheed <47912291+Faisal-Alsrheed@users.noreply.github.com> Date: Thu, 31 Aug 2023 13:33:37 +0000 Subject: [PATCH 5/5] fix reduce_shape + add tests operation_utils --- keras_core/ops/operation_utils_test.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/keras_core/ops/operation_utils_test.py b/keras_core/ops/operation_utils_test.py index 111520214..e0ec7c6fd 100644 --- a/keras_core/ops/operation_utils_test.py +++ b/keras_core/ops/operation_utils_test.py @@ -184,10 +184,3 @@ def test_reduce_shape_out_of_order_axes_no_keepdims(self): output_shape = operation_utils.reduce_shape(input_shape, axes) expected_output_shape = (1, 1) self.assertEqual(output_shape, expected_output_shape) - - def test_reduce_shape_with_negative_axes(self): - input_shape = (1, 4, 4, 1) - axes = [-2, -3] - output_shape = operation_utils.reduce_shape(input_shape, axes) - expected_output_shape = (1, 1) - self.assertEqual(output_shape, expected_output_shape)