我想用 documentation 或代码中没有提到的 PyTorch 卷积做两件事:

  • 我想用这样的固定内核创建一个卷积:
    000010000
    000010000
    100010001
    000010000
    000010000
    

    我猜,水平方面就像膨胀,但垂直部分是不同的。我看到 dilation 可以作为代码中的参数使用,但它必须是标量或单元素元组(不是每个维度一个元素),所以我认为它不能在这里做我想做的事。
  • 我希望我的卷积像环形一样“环绕”,而不是使用填充。

    编辑添加:我看到有一个 open issue ,它也提供了一个次优的 workaround 。所以,我想还没有“正确”的方法来做到这一点。
  • 最佳答案

  • torch.nn.conv2d() (实例化自己的可训练内核)不同, torch.nn.functional.conv2d() 将矩阵和内核作为参数,因此您可以将任何自定义内核传递给它。
  • 正如 @zou3519Github issue 中所建议的(链接到你自己提到的 issue),您可以通过“在 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
    

  • (previous) torch.nn.functional 模块中, torch.nn.functional.pad() 也可以作为参数 mode=reflect ,我相信这是你想要的(?)。您可以使用此方法在执行卷积之前手动填充输入矩阵。 (注意:您还有 torch.nn.ReflectionPad2d 层,专门为反射固定 2D 填充量身定制)
  • 关于padding - PyTorch 中的自定义卷积核和环形卷积,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50635736/

    10-13 02:13