数组填充 Numpy

Array Padding Numpy

我有以下矩阵:

x = \
    np.array([[[[0.99256822,  0.63019905],
                [0.77484078,  0.27471319]],

               [[0.94722451,  0.95948516],
                [0.81838252,  0.48979609]],

               [[0.81673764,  0.9388614],
                [0.57575844,  0.82265243]]],


              [[[0.95485566,  0.94870753],
                [0.92680463,  0.90044481]],

               [[0.90128127,  0.98683992],
                  [0.9115591,  0.85900321]],

               [[0.949711,    0.85709163],
                  [0.70392261,  0.91043368]]]])

它的尺寸为:2,3,2,2。我想要做的是将它与以下矩阵相乘:

y = \
    np.array([[[[ 0.,          0.,          0.63019905,  0.        ],
   [ 0.,          0.99256822,  0.,          0.        ],
   [ 0.77484078,  0.,          0.,          0.27471319],
   [ 0.,          0.,          0.,          0.        ]],
  [[ 0.,          0.,          0.,          0.        ],
   [ 0.94722451,  0.,          0.,          0.95948516],
   [ 0.81838252, 0.,          0.,          0.        ],
   [ 0.,          0.,          0.48979609,  0.        ]],

  [[ 0.,          0.,          0.,          0.        ],
   [ 0.,          0.81673764,  0.,          0.9388614 ],
   [ 0.,          0.,          0.,          0.82265243],
   [ 0.57575844,  0.,          0.,          0.        ]]],
 [[[ 0.,          0.95485566,  0.,          0.        ],
   [ 0.,          0.,          0.,          0.94870753],
   [ 0.,          0.92680463,  0.,          0.        ],
   [ 0.,          0.,          0.,          0.90044481]],

  [[ 0.,          0.90128127,  0.,          0.        ],
   [ 0.,          0.,          0.,          0.98683992],
   [ 0.,          0.9115591,   0.,          0.        ],
   [ 0.,          0.,          0.,          0.85900321]],

  [[ 0.,          0.,          0.,          0.85709163],
   [ 0.,          0.949711,    0.,          0.        ],
   [ 0.,          0.70392261,  0.,          0.91043368],
   [ 0.,          0.,          0.,          0.        ]]]])

这有尺寸 2,3,4,4。所以我需要做的是以这样一种方式填充第一个矩阵,即我们将每个条目复制 4 次,以便可以进行乘法(结果中的 3 将详细说明为 0,最终结果将是乘法我想)。因此,我需要将第一个矩阵转换成如下所示:

    [[[[ 0.99256822          0.99256822          0.63019905  0.63019905        ]
       [ 0.99256822          0.99256822          0.63019905  0.63019905        ]
        [ 0.77484078         0.77484078          0.27471319  0.27471319]
        [ 0.77484078         0.77484078          0.27471319  0.27471319        ]]

等等...

更新:

 def bprop(self, inputs, outputs, grads_wrt_outputs):

        m,n = grads_wrt_outputs.shape[:2]
        o = inputs.shape[2]
        p = inputs.shape[3]
        return (self.mask.reshape(m,n,2,2,2,2)*grads_wrt_outputs[:,:,:,None,:,None]).reshape(m,n,o,p) 

这是我正在使用的场景。

您要找的函数是np.repeat。我沿着最后两个维度重复 x 矩阵两次,如下所示:

>>> x = np.repeat(x, 2, axis=(2))
>>> x = np.repeat(x, 2, axis=(3))
>>> x
  [[[[ 0.99256822  0.99256822  0.63019905  0.63019905]
   [ 0.99256822  0.99256822  0.63019905  0.63019905]
   [ 0.77484078  0.77484078  0.27471319  0.27471319]
   [ 0.77484078  0.77484078  0.27471319  0.27471319]]

  [[ 0.94722451  0.94722451  0.95948516  0.95948516]
   [ 0.94722451  0.94722451  0.95948516  0.95948516]
   [ 0.81838252  0.81838252  0.48979609  0.48979609]
   [ 0.81838252  0.81838252  0.48979609  0.48979609]]
   ...
>>> x.shape
(2, 3, 4, 4)
>>> y.shape
(2, 3, 4, 4)

现在两个矩阵的形状相似,可以将它们相乘:

>>> x * y
[[[[ 0.          0.          0.39715084  0.        ]
   [ 0.          0.98519167  0.          0.        ]
   [ 0.60037823  0.          0.          0.07546734]
   [ 0.          0.          0.          0.        ]]

  [[ 0.          0.          0.          0.        ]
   [ 0.89723427  0.          0.          0.92061177]
   [ 0.66974995  0.          0.          0.        ]
   [ 0.          0.          0.23990021  0.        ]]

  [[ 0.          0.          0.          0.        ]
   [ 0.          0.66706037  0.          0.88146073]
   [ 0.          0.          0.          0.67675702]
   [ 0.33149778  0.          0.          0.        ]]]


 [[[ 0.          0.91174933  0.          0.        ]
   [ 0.          0.          0.          0.90004598]
   [ 0.          0.85896682  0.          0.        ]
   [ 0.          0.          0.          0.81080086]]

  [[ 0.          0.81230793  0.          0.        ]
   [ 0.          0.          0.          0.97385303]
   [ 0.          0.83093999  0.          0.        ]
   [ 0.          0.          0.          0.73788651]]

  [[ 0.          0.          0.          0.73460606]
   [ 0.          0.90195098  0.          0.        ]
   [ 0.          0.49550704  0.          0.82888949]
   [ 0.          0.          0.          0.        ]]]]

我假设 ab 分别是两个数组。

方法 #1

要获得重复的版本,我们可以使用 np.broadcast_toa 扩展为 6D,然后重塑为 4D -

a6D = a[:,:,:,None,:,None]
m,n,p,q = a.shape
r,s = b.shape[-2:]
a_repeated = np.broadcast_to(a6D, (m,n,p,r//p,q,s//q)).reshape(b.shape)

然后,使用 a_repeatedb 进行逐元素乘法。

方法 #2(内存效率高的方法)

您可以通过添加新轴将 a 扩展到 6D,从而避免任何实际重复或平铺以提高内存效率,使用 6D 重塑 b 最后重塑回 4D 输出。因此,对于 4D 数组 ab,我们将有 -

m,n,p,q = a.shape
r,s = b.shape[-2:]
out = (b.reshape(m,n,p,r//p,q,s//q)*a[:,:,:,None,:,None]).reshape(b.shape)