数组填充 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. ]]]]
我假设 a
和 b
分别是两个数组。
方法 #1
要获得重复的版本,我们可以使用 np.broadcast_to
将 a
扩展为 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_repeated
与 b
进行逐元素乘法。
方法 #2(内存效率高的方法)
您可以通过添加新轴将 a
扩展到 6D
,从而避免任何实际重复或平铺以提高内存效率,使用 6D
重塑 b
最后重塑回 4D
输出。因此,对于 4D
数组 a
和 b
,我们将有 -
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)
我有以下矩阵:
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. ]]]]
我假设 a
和 b
分别是两个数组。
方法 #1
要获得重复的版本,我们可以使用 np.broadcast_to
将 a
扩展为 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_repeated
与 b
进行逐元素乘法。
方法 #2(内存效率高的方法)
您可以通过添加新轴将 a
扩展到 6D
,从而避免任何实际重复或平铺以提高内存效率,使用 6D
重塑 b
最后重塑回 4D
输出。因此,对于 4D
数组 a
和 b
,我们将有 -
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)