【问题标题】:How to write a kernel for pytorch convolution function?如何为pytorch卷积函数编写内核?
【发布时间】:2021-10-03 12:33:56
【问题描述】:

我想对矩阵进行卷积

np.random.seed(0)
m_numpy = np.random.choice([0,1],p=(0.5,0.5),size=(6,6))
m = torch.from_numpy(Z_numpy).type(torch.FloatTensor)
tensor([[1., 1., 1., 1., 0., 1.],
        [0., 1., 1., 0., 1., 1.],
        [1., 1., 0., 0., 0., 1.],
        [1., 1., 1., 1., 0., 1.],
        [0., 1., 0., 1., 1., 0.],
        [0., 1., 0., 1., 0., 1.]])

带内核:

krnl = torch.tensor([[1,1,1],
                            [1,0,1],
                            [1,1,1]])

krnl
tensor([[1, 1, 1],
        [1, 0, 1],
        [1, 1, 1]])

但是使用来自torch.nn.functional 的函数conv2d 我看不到在哪里写这些张量。这样做conv2d(m, krnl,mode='same') 会带来错误:

TypeError: conv2d() received an invalid combination of arguments - got (Tensor, Tensor, mode=str), but expected one of:
 * (Tensor input, Tensor weight, Tensor bias, tuple of ints stride, tuple of ints padding, tuple of ints dilation, int groups)
 * (Tensor input, Tensor weight, Tensor bias, tuple of ints stride, str padding, tuple of ints dilation, int groups)

怎么做?

【问题讨论】:

标签: python pytorch convolution


【解决方案1】:

在下面的代码中,我将m_numpy 的尺寸更改为(1,1,6,6)Conv2d 需要这个尺寸,然后也匹配kernel 尺寸,使用功能模块的 conv2d,如here 中所述

import numpy as np
import torch
import torch.nn.functional as F

np.random.seed(0)
m_numpy = np.random.choice([0,1],p=(0.5,0.5),size=(1,1,6,6))
m = torch.from_numpy(m_numpy).type(torch.FloatTensor)

print(m)

weights = torch.tensor([[[[1.,1.,1.],
                          [1.,0.,1.],
                          [1.,1.,1.]]]])

print(weights)

output = F.conv2d(m, weights, padding = 1)

print(output)

给出输出

tensor([[[[1., 1., 1., 1., 0., 1.],
          [0., 1., 1., 0., 1., 1.],
          [1., 1., 0., 0., 0., 1.],
          [1., 1., 1., 1., 0., 1.],
          [0., 1., 0., 1., 1., 0.],
          [0., 1., 0., 1., 0., 1.]]]])
tensor([[[[1., 1., 1.],
          [1., 0., 1.],
          [1., 1., 1.]]]])
tensor([[[[2., 4., 4., 3., 4., 2.],
          [5., 6., 5., 4., 4., 3.],
          [4., 6., 6., 4., 5., 3.],
          [4., 5., 5., 3., 5., 2.],
          [4., 4., 7., 4., 5., 3.],
          [2., 1., 4., 2., 4., 1.]]]])

【讨论】:

    【解决方案2】:

    权重张量和输入张量都必须是四维的:

    • 输入张量的形状是(batch_size, n_channels, height, width)。在这里,您希望从单通道 6x6 实例推断, (1, 1, 6, 6) 的形状。

    • 提供给F.conv2d 的权重张量的形状对应于(n_filters, n_channels, kernel_height, kernel_width)。在您的情况下,您似乎只有一个带有单个通道的过滤器,kernel_heightkernel_width 都等于 3

    另外,两个操作数的 dtype 必须为 float

    >>> krnl = tensor([[1., 1., 1.],
                       [1., 0., 1.],
                       [1., 1., 1.]])
    
    >>> F.conv2d(m.reshape(1,1,*m.shape), krnl.reshape(1,1,*krnl.shape), padding='same')
    tensor([[[[2., 4., 4., 3., 4., 2.],
              [5., 6., 5., 4., 4., 3.],
              [4., 6., 6., 4., 5., 3.],
              [4., 5., 5., 3., 5., 2.],
              [4., 4., 7., 4., 5., 3.],
              [2., 1., 4., 2., 4., 1.]]]])
    

    或者,要重塑为 (1, 1, h, w),您可以这样做:

    >>> F.conv2d(m[None, None], krnl[None, None], padding='same')
    # yields the same result
    

    import torch.nn.functional as F

    【讨论】:

      猜你喜欢
      • 2018-05-03
      • 1970-01-01
      • 2018-11-11
      • 2022-01-15
      • 1970-01-01
      • 2011-10-23
      • 2016-12-31
      • 2020-09-23
      • 2019-09-25
      相关资源
      最近更新 更多