PyTorch中的自定义卷积核和环形卷积。

4
我希望对PyTorch卷积进行两个操作,这些操作在文档或代码中没有提到:
  1. I want to create a convolution with a fixed kernel like this:

    000010000
    000010000
    100010001
    000010000
    000010000
    

    The horizontal aspect is like dilation, I guess, but the vertical part is different. I see that dilation is available as a parameter in the code, but it has to be a scalar or single-element tuple (not one element per dimension), so I don't think it can do what I want here.

  2. I would like my convolutions to "wrap around" like a toroid, rather than use padding.

    EDIT TO ADD: I see that there is an open issue for this , which also provides a suboptimal workaround. So, I guess that there's no "right" way to do it, yet.

1个回答

5
  1. torch.nn.conv2d()不同的是(它实例化自己的可训练核),torch.nn.functional.conv2d()接受您的矩阵和核作为参数,因此您可以传递任何自定义核。

  2. 正如@zou3519Github问题中建议的那样(链接到您自己提到的问题),您可以通过“在nxn网格中重复张量,然后裁剪出您需要的部分”来实现2D循环填充:

def circular_pad_2d(x, pad=(1, 1)):
   # Snipped by @zou3519 (https://github.com/zou3519)
   return x.repeat(*x_shape[:2])[
        (x.shape[0]-pad[0]):(2*x.shape[0]+pad[0]), 
        (x.shape[1]-pad[1]):(2*x.shape[1]+pad[1])
   ]

# Example:
x = torch.tensor([[1,2,3],[4,5,6]])
y = circular_pad_2d(x, pad=(2, 3))
print(y)
#     1     2     3     1     2     3     1     2     3
#     4     5     6     4     5     6     4     5     6
#     1     2     3     1     2     3     1     2     3
#     4     5     6     4     5     6     4     5     6

  1. (previous)torch.nn.functional 模块中,torch.nn.functional.pad() 也可以接受参数 mode=reflect,我想这就是你想要的吧?你可以使用此方法在执行卷积之前手动填充输入矩阵。 (注意:你还可以使用 torch.nn.ReflectionPad2d 层,专门为反射固定2D填充而设计)

谢谢!1. 我之前没有意识到可训练和不可训练之间的区别,这对我很有帮助。在torch.nn.functional.conv2d()中,如果我理解正确,filters是自定义内核吗?2. 环形不同于反射,参见例如https://github.com/pytorch/pytorch/issues/6124 - 这似乎是一个开放请求,目前除了使用解决方法外还无法实现。 - jmmcd
1
  1. 是的,将你的内核作为过滤器(由参数weights定义)给出。
  2. 啊,确实是我不好。那么这个问题中提到的解决方法呢?即在卷积之前自己实现二维循环填充,应用于你的矩阵上。(我已经相应更新了我的回答)
- benjaminplanche
是的,我在我的编辑中链接了它 - 看起来它似乎被视为一种解决方法。现在先这样吧。 - jmmcd
2
看起来torch.nn.functional.pad现在支持circular填充。 - Vaelus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接