【问题标题】:how to perform a backwards correlation/convolution in python如何在python中执行反向相关/卷积
【发布时间】:2020-01-23 03:27:34
【问题描述】:

我正在尝试对 2 个矩阵执行反向相关(至少我认为它是这样称呼的)以获得结果矩阵。

注意:反向卷积也可以,因为我将其应用于 CNN。

我有以下两个矩阵:

vals:

[[ 2  1 -3 -4 -4]
 [ 2 -3  3  1  2]
 [ 2  5 -6  6 -2]
 [-5  4  1  5  4]
 [ 0  0  1 -3 -4]]

w0:

[[[0,  1, -1],
  [1, -1,  0],
  [0,  0,  0]],

 [[1,  0,  0],
  [0, -1,  1],
  [1,  0,  1]],

 [[ 1, -1,  0],
  [-1,  0, -1],
  [-1,  0,  1]]]

我本质上想应用一个滑动窗口,除了在这种情况下,w0 的所有值都乘以vals 中每个点的标量值,然后加上相邻的值。

假设步幅为 1,填充相同(wrt vals),以下代码给出了我想要的结果:

concat = np.zeros((3,7,7))
for k in range(len(w0)):
    for i in range(len(vals)):
        for j in range(len(vals[i])):
            v = w0[k] * vals[i][j]
            concat[k][i:i+v.shape[0], j:j+v.shape[1]] += v
print(concat)

导致:

[[[  0.   2.  -1.  -4.  -1.   0.   4.]
  [  2.   1.  -9.   5.  -2.   5.  -2.]
  [  2.  -3.   9. -13.  13. -10.   2.]
  [  2.  -2.  -2.   9.  -4.   1.  -4.]
  [ -5.   9.  -3.   5.  -5.  -5.   4.]
  [  0.   0.   1.  -4.  -1.   4.   0.]
  [  0.   0.   0.   0.   0.   0.   0.]]

 [[  2.   1.  -3.  -4.  -4.   0.   0.]
  [  2.  -5.   4.   5.   3.   0.  -4.]
  [  4.   4.  -2.  -3.  -7.  -5.  -2.]
  [ -3.  -1.   3.  14.  -3.   9.   0.]
  [  2.  10. -12.  11. -16.   7.   2.]
  [ -5.   4.  -4.   8.   9.   6.   0.]
  [  0.   0.   1.  -3.  -3.  -3.  -4.]]

 [[  2.  -1.  -4.  -1.   0.   4.   0.]
  [  0.  -6.   7.   1.   8.   2.   4.]
  [ -2.   5. -11.  19. -12.  -3.  -6.]
  [ -9.   7.   0. -11.   8.  -9.   4.]
  [  3.  -9.  13. -14. -10.   5.  -6.]
  [  5.  -4.  -7.   2.   0.   8.   8.]
  [  0.   0.  -1.   3.   5.  -3.  -4.]]]

然后我会缩小以排除填充,所以:

print(concat[:,1:-1, 1:-1])

>>> [[[  1.  -9.   5.  -2.   5.]
      [ -3.   9. -13.  13. -10.]
      [ -2.  -2.   9.  -4.   1.]
      [  9.  -3.   5.  -5.  -5.]
      [  0.   1.  -4.  -1.   4.]]

     [[ -5.   4.   5.   3.   0.]
      [  4.  -2.  -3.  -7.  -5.]
      [ -1.   3.  14.  -3.   9.]
      [ 10. -12.  11. -16.   7.]
      [  4.  -4.   8.   9.   6.]]

     [[ -6.   7.   1.   8.   2.]
      [  5. -11.  19. -12.  -3.]
      [  7.   0. -11.   8.  -9.]
      [ -9.  13. -14. -10.   5.]
      [ -4.  -7.   2.   0.   8.]]]

concat 的两个结果中的任何一个都可以,但最好是包含填充的那个。

有谁知道不使用 python 循环的方法吗?我更喜欢使用 numpy 或其他一些库,因为它执行相同的计算必然比我的代码更快。

编辑:

我还想对w0 执行相同类型的后向相关,因此再次使用vals 而是使用:

a:

[[[2, 0, 2, 2, 2],
  [1, 1, 0, 2, 0],
  [0, 0, 1, 2, 2],
  [2, 2, 2, 0, 0],
  [1, 0, 1, 2, 0]],

 [[1, 2, 1, 0, 1],
  [0, 2, 0, 0, 1],
  [0, 0, 2, 2, 1],
  [2, 0, 1, 0, 2],
  [0, 1, 2, 2, 2]],

 [[0, 0, 2, 2, 2],
  [0, 1, 2, 1, 0],
  [0, 0, 0, 2, 0],
  [0, 2, 0, 0, 2],
  [0, 0, 2, 2, 1]]]

在这种情况下,沿a 使用 3x3 滑动窗口,填充为 1,并将滑动窗口中的所有值乘以 vals 中标量值的关联索引,最后得到相同的输出大小为w0。下面的代码实现了这一点:

concat = np.zeros((3,3,3))
for k in range(len(w0)):
    f = np.pad(a[k], 1)
    for i in range(len(vals)):
        for j in range(len(vals[i])):
            v = f[i:i+w0.shape[1], j:j+w0.shape[2]] * vals[i][j]
            concat[k] += v

与:

print(concat)
>>>[[[  4.  56.   8.]
     [  1. -20.   1.]
     [ 22.  12.  21.]]

    [[  7.  18.  21.]
     [  5. -22.  20.]
     [ 35.  26.  33.]]

    [[ 20.  13.   4.]
     [-25.   2. -26.]
     [ -5.  15.  38.]]]

【问题讨论】:

    标签: python numpy scipy conv-neural-network


    【解决方案1】:

    scipy.signalconvolve其实就是你想要的:

    from scipy.signal import convolve
    
    convolve(vals[None, :, :], w0)[:, 1:-1, 1:-1]
    Out[]: 
    array([[[  1,  -9,   5,  -2,   5],
            [ -3,   9, -13,  13, -10],
            [ -2,  -2,   9,  -4,   1],
            [  9,  -3,   5,  -5,  -5],
            [  0,   1,  -4,  -1,   4]],
    
           [[ -5,   4,   5,   3,   0],
            [  4,  -2,  -3,  -7,  -5],
            [ -1,   3,  14,  -3,   9],
            [ 10, -12,  11, -16,   7],
            [  4,  -4,   8,   9,   6]],
    
           [[ -6,   7,   1,   8,   2],
            [  5, -11,  19, -12,  -3],
            [  7,   0, -11,   8,  -9],
            [ -9,  13, -14, -10,   5],
            [ -4,  -7,   2,   0,   8]]])
    

    【讨论】:

    • 谢谢!我实际上是在做一些实验,发现先做scipy.signal.correlate 然后再做np.flip(w0) 给了我我需要的东西。现在才想起 signal.convolve 就是这么做的哈哈
    【解决方案2】:

    你可以看看scipy.ndimage.filters.convolve

    例如:

    >>> a = np.array([[1, 2, 0, 0],
    ....    [5, 3, 0, 4],
    ....    [0, 0, 0, 7],
    ....    [9, 3, 0, 0]])
    >>> k = np.array([[1,1,1],[1,1,0],[1,0,0]])
    >>> from scipy import ndimage
    >>> ndimage.convolve(a, k, mode='constant', cval=0.0)
    array([[11, 10,  7,  4],
           [10,  3, 11, 11],
           [15, 12, 14,  7],
           [12,  3,  7,  0]])
    

    【讨论】:

    • 这是一个普通的卷积。我希望做一个反向相关。
    猜你喜欢
    • 1970-01-01
    • 2017-04-07
    • 1970-01-01
    • 2017-08-15
    • 2013-06-08
    • 2016-11-11
    • 1970-01-01
    • 1970-01-01
    • 2013-12-17
    相关资源
    最近更新 更多