pythonpytorchmax-pooling

PyTorch MaxPool2D unexpected behavior with padding=1


I was playing around with MaxPool2D in PyTorch and discovered strange behavior when setting padding=1. Here is what I got:

Code:

import torch
from torch.nn.functional import max_pool2d

TEST = 1


def test_maxpool(negative=False, tnsr_size=2, kernel_size=2, stride=2, padding=0):
    """Test MaxPool2D.
    """
    global TEST
    print(f'=== TEST {TEST} ===')
    print(*[f'{i[0]}: {i[1]}' for i in locals().items()], sep=' | ')

    inp = torch.arange(1., tnsr_size ** 2 + 1).reshape(1, tnsr_size, tnsr_size)
    inp = -inp if negative else inp

    print('In:')
    print(inp)

    out = max_pool2d(inp, kernel_size, stride, padding=padding)
    print('Out:')
    print(out)
    print()
    TEST += 1


test_maxpool()
test_maxpool(True)

test_maxpool(padding=1)
test_maxpool(True, padding=1)

Out:

=== TEST 1 ===
negative: False | tnsr_size: 2 | kernel_size: 2 | stride: 2 | padding: 0
In:
tensor([[[1., 2.],
         [3., 4.]]])
Out:
tensor([[[4.]]])

=== TEST 2 ===
negative: True | tnsr_size: 2 | kernel_size: 2 | stride: 2 | padding: 0
In:
tensor([[[-1., -2.],
         [-3., -4.]]])
Out:
tensor([[[-1.]]])

=== TEST 3 ===
negative: False | tnsr_size: 2 | kernel_size: 2 | stride: 2 | padding: 1
In:
tensor([[[1., 2.],
         [3., 4.]]])
Out:
tensor([[[1., 2.],
         [3., 4.]]])

=== TEST 4 ===
negative: True | tnsr_size: 2 | kernel_size: 2 | stride: 2 | padding: 1
In:
tensor([[[-1., -2.],
         [-3., -4.]]])
Out:
tensor([[[-1., -2.],
         [-3., -4.]]])

Tests 1, 2, 3 are fine but Test 4 is weird, I expected to get [[0 0], [0 0]] tensor:

In:
[[-1 -2]
 [-3 -4]]

+ padding -> 

[[ 0  0  0  0]
 [ 0 -1 -2  0]
 [ 0 -3 -4  0]
 [ 0  0  0  0]]

-> kernel_size=2, stride=2 ->

[[0 0]
 [0 0]]

According to Test 3 zero padding was used but Test 4 produced controversial result.

What kind of padding (if any) was that? Why does MaxPool2D behave like that?

pytorch 1.3.1


Solution

  • This was expected behavior since negative infinity padding is done by default.

    The documentation for MaxPool is now fixed. See this PR: Fix MaxPool default pad documentation #59404 .