Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

Average pool with padding calculation different from TF and Pytorch #10194

Closed
rajanksin opened this issue Mar 22, 2018 · 6 comments
Closed

Average pool with padding calculation different from TF and Pytorch #10194

rajanksin opened this issue Mar 22, 2018 · 6 comments

Comments

@rajanksin
Copy link
Contributor

Comparing avg pool behavior on mxnet vs Tendorflow/pytorch , seems like when we calculate the avgpool , we count the padding values while taking mean.

Input : 
[[[[  1.   2.   3.   4.   5.]
   [  6.   7.   8.   9.  10.]
   [ 11.  12.  13.  14.  15.]
   [ 16.  17.  18.  19.  20.]
   [ 21.  22.  23.  24.  25.]]]]
<NDArray 1x1x5x5 @cpu(0)>

MXNET:

import mxnet as mx
x = mx.nd.array(np.arange(1, 26).reshape(1,1,5,5))
output  = mx.ndarray.Pooling(data=x, kernel=(5,5), pad=(2,2), pool_type='avg')

[[[[  2.51999998   3.5999999    4.80000019   4.07999992   3.24000001]
   [  4.55999994   6.4000001    8.39999962   7.03999996   5.51999998]
   [  7.19999981  10.          13.          10.80000019   8.39999962]
   [  6.96000004   9.60000038  12.39999962  10.23999977   7.92000008]
   [  6.11999989   8.39999962  10.80000019   8.88000011   6.84000015]]]]
<NDArray 1x1x5x5 @cpu(0)>

Tensor Flow :

#(TF avg pool only supports NHWC ,hence different reshape)
x = np.arange(1,26, dtype=np.float32).reshape(1,5,5,1)
tf.reset_default_graph()
x = tf.get_variable('x', initializer = x)
print(x)
y=tf.nn.avg_pool(x,ksize=[1,5,5,1], strides=[1,1,1,1],padding='SAME')
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
   sess.run(init_op)
   print(sess.run(y))

[[[[  7. ][  7.5][  8. ][  8.5][  9. ]]
  [[  9.5][ 10. ][ 10.5][ 11. ][ 11.5]]
  [[ 12. ][ 12.5][ 13. ][ 13.5][ 14. ]]
  [[ 14.5][ 15. ][ 15.5][ 16. ][ 16.5]]
  [[ 17. ][ 17.5][ 18. ][ 18.5] [ 19. ]]]]

Looking closely at the first kernel window with padding:

0 0 0  0  0
0 0 0  0  0
0 0 1  2  3
0 0 6  7  8
0 0 11 12 13
Sum = (1+2+3+6+7+8+11+12+13) = 63
MXNET: 63/25 = 2.52
TF  : 63/9  = 7 . (Pytorch also gets the same value)

Is this behavior by design?
Although this seems incorrect , as avg value will be less than actual mean of the data.

@nswamy @anirudhacharya @sandeep-krishnamurthy @lupesko

@sxjscience
Copy link
Member

I remember we've discussed it before but cannot find the issue now...

@rajanksin
Copy link
Contributor Author

@sxjscience do we know if we are planning to change logic similar to other frameworks?

@sxjscience
Copy link
Member

I think it will break lots of pretrained models. We'd better keep the current implementation. Need to ask @piiswrong

@sxjscience
Copy link
Member

@spidydev We've discussed it before: #2753. The proposal is to add a valid flag like in CuDNN. However, the thread becomes inactive. I think we can add a padding_convention flag to the operator, which will ignore the padded values once set to be "valid".

@anirudhacharya
Copy link
Member

Is the following proposed solution okay? - to add a ‘padding_convention’ flag so that the operator will ignore the padded values when the flag is set. This is one way to fix the discrepancy without breaking any existing pre-trained models.

@szha @piiswrong @zheng-da

@anirudhacharya
Copy link
Member

anirudhacharya commented Aug 2, 2018

@spidydev @nswamy please close this issue as it has been addressed. documentation for the change - https://mxnet.incubator.apache.org/api/python/ndarray/ndarray.html?highlight=poolin#mxnet.ndarray.Pooling

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants