PyTorch Circular Padding in one Dimension

Viewed 3527

for a convolution i want to apply a circular padding in one dimension and a zero padding in all other dimension. How can i do this?

For the convolution there are 28 channels and fore the the data is described in spherical bins. There are 20 bins for radius times 20 bins for polar times 20 bins for inclination. The circular padding should only be applied for the inclination.

Small Example

# Example:
x = torch.tensor([[1,2,3],
                  [4,5,6],
                  [7,8,9]])
y = sphere_pad(x, pad=(0, 1))

# y is now tensor([[3, 1, 2, 3, 1],
#                  [6, 4, 5, 6, 4],
#                  [9, 7, 8, 9, 7]])

I have tried to apply

def sphere_pad(x, pad=(1,1)):
    return x.repeat(*x.shape)[
        (x.shape[0]-pad[0]):(2*x.shape[0]+pad[0]), 
        (x.shape[1]-pad[1]):(2*x.shape[1]+pad[1])]

and then apply a convolution with a normal zero padding ( and no padding in the last dimension). This works for a small example but this method exceeds the GPU memory for the actual problem size. Are there other ways?

2 Answers

Using numpy, you could do a wrap padding so the array gets wrapped along the second axis:

np.pad(x, ((0,0),(1,1)), mode='wrap')
array([[3, 1, 2, 3, 1],
       [6, 4, 5, 6, 4],
       [9, 7, 8, 9, 7]])

This functionality was added by #17240. However, for some (strange) reason circular padding is only supported by 3D, 4D and 5D tensors. If you already have a 2D tensor, you need to convert it to 3D before doing it directly in pytorch:

>>> a = torch.randint(0, 9, (1, 3, 3))
>>> a
tensor([[[4, 2, 5],
         [2, 2, 8],
         [3, 2, 8]]])
>>> F.pad(a, (1, 1), mode='circular')
tensor([[[5, 4, 2, 5, 4],
         [8, 2, 2, 8, 2],
         [8, 3, 2, 8, 3]]])
Related