Conv2d and padding_mode: circular vs reflect

Hi All -

I was looking into padding-mode for nn.Conv2d. In the docs it doesn’t describe the options but in the source code its says

padding_mode (string, optional). Accepted values zeros and circular

Digging deeper, padding mode calls F.pad(), and F.pad() has the following options for mode

mode: 'constant', 'reflect', 'replicate' or 'circular'

I was originally looking to use “reflect”. Questions:

  • is reflect implemented but not in the docs (for nn.Conv2d)?
  • if not implemented, any particular reason?
  • i’ve never used “circular” padding before:
    • what is it?
    • when is it good to use?
    • is there general advice on if its best to use zero-padding/circular/reflect?
  • what is “replicate” (does it just extend the borders out with the edge values)

Thanks!

5 Likes

padding_mode of Con2d accept values zeros and circular only.

Looking the code of Conv2d:

class Conv2d(_ConvNd):
    def __init__(self, in_channels, out_channels, kernel_size, stride=1,
                 padding=0, dilation=1, groups=1,
                 bias=True, padding_mode='zeros'):
        kernel_size = _pair(kernel_size)
        stride = _pair(stride)
        padding = _pair(padding)
        dilation = _pair(dilation)
        super(Conv2d, self).__init__(
            in_channels, out_channels, kernel_size, stride, padding, dilation,
            False, _pair(0), groups, bias, padding_mode)

    def conv2d_forward(self, input, weight):
        if self.padding_mode == 'circular':
            expanded_padding = ((self.padding[1] + 1) // 2, self.padding[1] // 2,
                                (self.padding[0] + 1) // 2, self.padding[0] // 2)
            return F.conv2d(F.pad(input, expanded_padding, mode='circular'),
                            weight, self.bias, self.stride,
                            _pair(0), self.dilation, self.groups)
        return F.conv2d(input, weight, self.bias, self.stride,
                        self.padding, self.dilation, self.groups)

    def forward(self, input):
        return self.conv2d_forward(input, self.weight)

if padding_mode is not circular, the code

return F.conv2d(input, weight, self.bias, self.stride,
                        self.padding, self.dilation, self.groups)

will always be executed.