I have the following matrix:
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]]]])
It has dimensions: 2,3,2,2
. What I want to do is multiply it with the following matrix:
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. ]]]])
This has dimensions 2,3,4,4
. So what I need to do is to pad the first matrix in such a way that we have each entry copied 4 times, so that the multiplication can take place (3 of the results will elaborate to 0, and the final result will be the multiplication I want). Therefore, I need to convert the first matrix into something that looks like this:
[[[[ 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 ]]
and so on...
Update:
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)
This is the scenario I am using this in.
I am assuming a
and b
as the two arrays respectively.
To get that repeated version, we could extend a
to 6D
with np.broadcast_to
and then reshape to 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)
Then, use a_repeated
for element-wise multiplication with b
.
You can extend a
to 6D
by adding in new axes and thus avoiding any actual repeating or tiling for memory efficiency, perform element-wise multiplication with a 6D
reshaped b
and finally reshape back to 4D
output. Hence, for 4D
arrays a
and b
, we would have -
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)