diff options
author | Eric Kunze <eric.kunze@arm.com> | 2021-09-21 16:56:20 -0700 |
---|---|---|
committer | Eric Kunze <eric.kunze@arm.com> | 2021-09-24 16:19:50 -0700 |
commit | b37e7fb865744536b708c8baa49b6415eab07b04 (patch) | |
tree | 179ca5c9322f342993c82a67a16208c810d4ba10 | |
parent | f1b531ac7a0a045301d39ba14d5c1dc5dc691ddc (diff) | |
download | specification-b37e7fb865744536b708c8baa49b6415eab07b04.tar.gz |
Don't allow pooling ops with excessive padding
Padding larger than the kernel size leads to the
odd effect where no values from the input tensor are used.
This leads to a divide by 0 in AVG_POOL2D, as it only divides
by the number of valid input values used, not padding.
Change MAX_POOL2D to have the same limitation for consistency.
Signed-off-by: Eric Kunze <eric.kunze@arm.com>
Change-Id: I9cd0c0619f88f570d30c83053280460ae3d1cbfb
-rw-r--r-- | chapters/tensor_ops.adoc | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/chapters/tensor_ops.adoc b/chapters/tensor_ops.adoc index 9c10450..ff5f25a 100644 --- a/chapters/tensor_ops.adoc +++ b/chapters/tensor_ops.adoc @@ -70,8 +70,9 @@ for_each(left_index in left_shape) { ==== AVG_POOL2D -This performs an average pooling over the given input tensor. A sliding window of size given by <kernel size> is passed over the input tensor, with the mean value being placed in the output tensor. - +This performs an average pooling over the given input tensor. +A sliding window of size given by <kernel size> is passed over the input tensor, with the mean value being placed in the output tensor. +When calculating the average, only the number of valid input tensor values, but not padding, are used to calculate the divisor. *Arguments:* |=== @@ -102,6 +103,11 @@ ERROR_IF(in_t != int8_t && output_zp != 0); // Zero point only for int8_t ERROR_IF(kernel_y < 1 || kernel_x < 1); // kernel size must be >= 1 ERROR_IF(stride_y < 1 || stride_x < 1); ERROR_IF(pad_top < 0 || pad_buttom < 0 || pad_left < 0 || pad_right < 0); +// Padding must be less than kernel size to avoid +// a divide-by-zero. +ERROR_IF(pad_right >= kernel_x || pad_left >= kernel_x); +ERROR_IF(pad_top >= kernel_y || pad_bottom >= kernel_y); + pad = flatten([0,0], pad, [0,0]); for_each(0 <= n < N, 0 <= oy < H, 0 <= ox < W, 0 <= c < C ) { in_t output_val; @@ -462,6 +468,11 @@ None ERROR_IF(kernel_y < 1 || kernel_x < 1); // kernel size must be >= 1 ERROR_IF(stride_y < 1 || stride_x < 1); ERROR_IF(pad_top < 0 || pad_buttom < 0 || pad_left < 0 || pad_right < 0); +// Padding must be less than kernel size, otherwise no +// input values will be used. +ERROR_IF(pad_right >= kernel_x || pad_left >= kernel_x); +ERROR_IF(pad_top >= kernel_y || pad_bottom >= kernel_y); + for_each(0 <= n < N, 0 <= oy < H, 0 <= ox < W, 0 <= c < C ) { in_t acc = minimum_value<in_t>; iy = oy * stride_y - pad_top; |