Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Even sized kernels with SAME padding in Tensorflow

In Tensorflow, SAME padding aims to produce a same sized output as the input, given a stride = 1, by padding the input with zeros as appropriate. For an odd sized kernel, for example like 5x5, it puts the center of the kernel (2,2) onto the first pixel of the input (0,0) and starts to convolve. Both in the x and y coordinates, 2 pixels of zero padding is needed then.

What if an even kernel, for example a 6x6 is used instead? It won't have a pixel's center as its actual center. How does VALID padding handle this? For example according to Image convolution with even-sized kernel the convention in the general image processing literature is to place one more pixel before the zero, like -3 -2 -1 0 1 2 in this case. Three pixel will be hit in the padding area. I refered to the Tensorflow documents for this, but could not find a clarifying answer.

like image 684
Ufuk Can Bicici Avatar asked Mar 05 '23 21:03

Ufuk Can Bicici


1 Answers

Like you say, the documentation does not seem to specify it clearly. Looking at the source of the 2D convolution kernel (conv_ops.cc), a comment explains:

// Total padding on rows and cols is
// Pr = (R' - 1) * S + (Kr - 1) * Dr + 1 - R
// Pc = (C' - 1) * S + (Kc - 1) * Dc + 1 - C
// where (R', C') are output dimensions, (R, C) are input dimensions, S
// is stride, (Dr, Dc) are dilations, (Kr, Kc) are filter dimensions.
// We pad Pr/2 on the left and Pr - Pr/2 on the right, Pc/2 on the top
// and Pc - Pc/2 on the bottom.  When Pr or Pc is odd, this means
// we pad more on the right and bottom than on the top and left.

So it seems you would get one extra padding at the right column and bottom row with even-sized kernels. We can look at one example:

import tensorflow as tf

input_ = tf.ones((1, 10, 10, 1), dtype=tf.float32)
kernel = tf.ones((6, 6, 1, 1), dtype=tf.float32)
conv = tf.nn.conv2d(input_, kernel, [1, 1, 1, 1], 'SAME')
with tf.Session() as sess:
    print(sess.run(conv)[0, :, :, 0])

Output:

[[16. 20. 24. 24. 24. 24. 24. 20. 16. 12.]
 [20. 25. 30. 30. 30. 30. 30. 25. 20. 15.]
 [24. 30. 36. 36. 36. 36. 36. 30. 24. 18.]
 [24. 30. 36. 36. 36. 36. 36. 30. 24. 18.]
 [24. 30. 36. 36. 36. 36. 36. 30. 24. 18.]
 [24. 30. 36. 36. 36. 36. 36. 30. 24. 18.]
 [24. 30. 36. 36. 36. 36. 36. 30. 24. 18.]
 [20. 25. 30. 30. 30. 30. 30. 25. 20. 15.]
 [16. 20. 24. 24. 24. 24. 24. 20. 16. 12.]
 [12. 15. 18. 18. 18. 18. 18. 15. 12.  9.]]

Indeed, it does look like extra zeros are added to the right and bottom sides.

like image 145
jdehesa Avatar answered Apr 03 '23 14:04

jdehesa