How do I do the following dot product in 3 dimensions with numpy?
I tried:
x = np.array([[[-1, 2, -4]], [[-1, 2, -4]]])
W = np.array([[[2, -4, 3], [-3, -4, 3]],
[[2, -4, 3], [-3, -4, 3]]])
y = np.dot(W, x.transpose())
but received this error message:
y = np.dot(W, x)
ValueError: shapes (2,2,3) and (2,1,3) not aligned: 3 (dim 2) != 1 (dim 1)
It's 2 dimensions equivalent is:
x = np.array([-1, 2, -4])
W = np.array([[2, -4, 3],
[-3, -4, 3]])
y = np.dot(W,x)
print(f'{y=}')
which will return:
y=array([-22, -17])
Also, y = np.dot(W,x.transpose())
will return the same answer.
How do I do the following dot product in 3 dimensions with numpy?
I tried:
x = np.array([[[-1, 2, -4]], [[-1, 2, -4]]])
W = np.array([[[2, -4, 3], [-3, -4, 3]],
[[2, -4, 3], [-3, -4, 3]]])
y = np.dot(W, x.transpose())
but received this error message:
y = np.dot(W, x)
ValueError: shapes (2,2,3) and (2,1,3) not aligned: 3 (dim 2) != 1 (dim 1)
It's 2 dimensions equivalent is:
x = np.array([-1, 2, -4])
W = np.array([[2, -4, 3],
[-3, -4, 3]])
y = np.dot(W,x)
print(f'{y=}')
which will return:
y=array([-22, -17])
Also, y = np.dot(W,x.transpose())
will return the same answer.
5 Answers
Reset to default 6The issue comes from the 3D transposition which does not transpose the axes you want by default. You need to specify the right axes during this call:
W @ x.transpose(0, 2, 1)
# Output:
# array([[[-22],
# [-17]],
#
# [[-22],
# [-17]]])
You might also want to use einsum
, this makes the matching dimensions more explicit:
np.einsum('ijk,ilk->ijl', W, x)
Output:
array([[[-22],
[-17]],
[[-22],
[-17]]])
First of all, I think @Jérôme Richard and @mozway have provided the most concise and efficient solutions. I cannot imagine better answers than those.
My approach is just for fun, if you would like to play with zip
+ map
np.array(list(map(lambda u: np.inner(*u), zip(W,x))))
gives
array([[[-22],
[-17]],
[[-22],
[-17]]])
Another possible solution:
np.sum(W * x, axis=2, keepdims=True)
By multiplying W
(shape (2, 2, 3)
) with x
(shape (2, 1, 3)
), numpy automatically broadcasts x
to match W
's shape, resulting in an element-wise product of shape (2, 2, 3)
. Summing this product along the last axis (axis=2
) with keepdims=True
yields the desired output shape (2, 2, 1)
.
Output:
array([[[-22],
[-17]],
[[-22],
[-17]]])
from einops import einsum
import numpy as np
x = np.array([[[-1, 2, -4]],
[[-1, 2, -4]]])
W = np.array([[[ 2, -4, 3],
[-3, -4, 3]],
[[2, -4, 3],
[-3, -4, 3]]])
res = einsum(W, x, 'b i j, b k j -> b i k')
res = np.squeeze(res)
'''
[[-22 -17]
[-22 -17]]
'''
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745219645a4617185.html
x.T
did you get exactly the same error? I think it couplained about a (3,1,2) aray. The docs fortranspose
,dot
,matmul/@
(andeinsum
) are all relevant. They are all clear about how axes are matched. – hpaulj Commented Feb 10 at 19:00