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]]])