'What is difference between the function numpy.dot(), @, and method .dot() for matrix-matrix multiplication?
Is there any difference? If not, what is preferred by convention? The performance seems to be almost the same.
a=np.random.rand(1000,1000)
b=np.random.rand(1000,1000)
%timeit a.dot(b) #14.3 ms ± 374 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit np.dot(a,b) #14.7 ms ± 315 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit a @ b #15.1 ms ± 779 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Solution 1:[1]
They are almost identical with a few exceptions.
a.dot(b) and np.dot(a, b) are exactly the same. See numpy.dot and ndarray.dot.
However, looking at the documentation of numpy.dot:
If both a and b are 2-D arrays, it is matrix multiplication, but using
matmulora @ bis preferred.
a @ b corresponds to numpy.matmul(a, b). dot and matmul differ as follows:
matmuldiffers fromdotin two important ways:
- Multiplication by scalars is not allowed, use
*instead.- Stacks of matrices are broadcast together as if the matrices were elements, respecting the signature
(n,k),(k,m)->(n,m):>>> a = np.ones([9, 5, 7, 4]) >>> c = np.ones([9, 5, 4, 3]) >>> np.dot(a, c).shape (9, 5, 7, 9, 5, 3) >>> np.matmul(a, c).shape (9, 5, 7, 3) >>> # n is 7, k is 4, m is 3
Solution 2:[2]
In my opinion, what best description and explanation is a clear example:
# How and when to use dot or matmul (@) ? # suppose all B values of dense nnet is 0
inp=np.random.random((20,10,100,4)) # 4 inputs 100 data 10 different cases 20 different groups
nnet1=np.random.random((4,3)) # 4 inputs 3 outputs
nnet2=np.random.random((3,5)) # 3 inputs 5 outputs
nnet3=np.random.random((5,2)) # 5 inputs 2 outputs
test1=inp@nnet1@nnet2@nnet3
test2=inp.dot(nnet1).dot(nnet2).dot(nnet3)
print(test1.shape)
print(test2.shape)
print(test1[5,3,7,1]) #6 th data 4th case second nnet output
print(test2[5,3,7,1]) #6 th data 4th case second nnet output
inp=np.random.random((20,10,100,4)) # 4 inputs 100 data 10 different cases 20 different groups
nnet1=np.random.random((9,4,3)) # 4 inputs 3 outputs # 9 different networks
nnet2=np.random.random((9,3,5)) # 3 inputs 5 outputs # 9 different networks
nnet3=np.random.random((9,5,2)) # 5 inputs 2 outputs # 9 different networks
test1=inp@nnet1[0]@nnet2[0]@nnet3[0] # for network 0
test2=inp.dot(nnet1@nnet2@nnet3)
print(test1.shape)
print(test2.shape)
print(test1[5,3,7,1]) #6 th data 4th case second nnet output
print(test2[5,3,7,0,1]) # 6 th data 4th case second nnet output for network 0
Output:
(20, 10, 100, 2)
(20, 10, 100, 2)
2.502277900709035
2.502277900709035
(20, 10, 100, 2)
(20, 10, 100, 9, 2)
0.6919054739155295
0.6919054739155295
Where you can compare and contrast each element to conditionally connect them which makes you understand deeply ...
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | iz_ |
| Solution 2 | Gediz GÜRSU |
