[英]Multiplying 3d matrix and 3d matrix
我正在嘗試將 3d 矩陣和 3d 矩陣相乘,我的矩陣如下:
Z = np.array([
[[0,0,0.25],[0.25,0.5,0.75],[0,0,0.25],[0.75,1.0,1.0],[0.75,1.0,1.0]],
[[0,0,0.25],[0,0,0.25],[0.5,0.75,1.0],[0,0,0.25],[0,0,0.25]],
[[0,0,0.25],[0,0,0.25],[0,0,0.25],[0,0.25,0.5],[0,0,0.25]],
[[0,0,0.25],[0.25,0.5,0.75],[0,0,0.25],(0,0,0.25),[0,0,0.25]],
[[0,0,0.25],[0,0,0.25],[0,0,0.25],[0,0,0.25],[0,0,0.25]]
])
print(Z)
print(type(Z))
print("np.shape = ",np.shape(Z))
形狀是 (5,5,3),我想像np.dot(Z,Z)
那樣做乘法,但它不能在 3d 矩陣中工作。
我見過使用np.tensordot(Z,Z,axes=?)
,但我不知道如何設置軸。
我建議您查看tensordot()
函數的文檔,以真正了解它對矩陣的作用:
import numpy as np
Z = np.array([
[[0,0,0.25],[0.25,0.5,0.75],[0,0,0.25],[0.75,1.0,1.0],[0.75,1.0,1.0]],
[[0,0,0.25],[0,0,0.25],[0.5,0.75,1.0],[0,0,0.25],[0,0,0.25]],
[[0,0,0.25],[0,0,0.25],[0,0,0.25],[0,0.25,0.5],[0,0,0.25]],
[[0,0,0.25],[0.25,0.5,0.75],[0,0,0.25],(0,0,0.25),[0,0,0.25]],
[[0,0,0.25],[0,0,0.25],[0,0,0.25],[0,0,0.25],[0,0,0.25]]
])
B = np.tensordot(Z, Z, axes=[1, 0])
print(B)
輸出:
[[[[0. 0. 0.4375]
[0.1875 0.375 0.8125]
[0.125 0.1875 0.625 ]
[0. 0. 0.4375]
[0. 0. 0.4375]]
[[0. 0. 0.625 ]
[0.25 0.5 1.125 ]
[0.25 0.375 1. ]
[0. 0. 0.625 ]
[0. 0. 0.625 ]]
[[0. 0. 0.8125]
[0.3125 0.625 1.4375]
[0.375 0.5625 1.375 ]
[0.1875 0.3125 1.0625]
[0.1875 0.25 1. ]]]
[[[0. 0. 0.125 ]
[0. 0. 0.125 ]
[0. 0. 0.125 ]
[0. 0.125 0.25 ]
[0. 0. 0.125 ]]
[[0. 0. 0.1875]
[0. 0. 0.1875]
[0. 0. 0.1875]
[0. 0.1875 0.375 ]
[0. 0. 0.1875]]
[[0. 0. 0.5 ]
[0.125 0.25 0.75 ]
[0.125 0.1875 0.6875]
[0.1875 0.5 0.9375]
[0.1875 0.25 0.6875]]]
[[[0. 0. 0. ]
[0. 0. 0. ]
[0. 0. 0. ]
[0. 0. 0. ]
[0. 0. 0. ]]
[[0. 0. 0.0625]
[0.0625 0.125 0.1875]
[0. 0. 0.0625]
[0. 0. 0.0625]
[0. 0. 0.0625]]
[[0. 0. 0.375 ]
[0.1875 0.375 0.75 ]
[0.125 0.1875 0.5625]
[0.1875 0.3125 0.625 ]
[0.1875 0.25 0.5625]]]
[[[0. 0. 0.0625]
[0. 0. 0.0625]
[0.125 0.1875 0.25 ]
[0. 0. 0.0625]
[0. 0. 0.0625]]
[[0. 0. 0.125 ]
[0. 0. 0.125 ]
[0.25 0.375 0.5 ]
[0. 0. 0.125 ]
[0. 0. 0.125 ]]
[[0. 0. 0.4375]
[0.125 0.25 0.6875]
[0.375 0.5625 1. ]
[0.1875 0.3125 0.6875]
[0.1875 0.25 0.625 ]]]
[[[0. 0. 0. ]
[0. 0. 0. ]
[0. 0. 0. ]
[0. 0. 0. ]
[0. 0. 0. ]]
[[0. 0. 0. ]
[0. 0. 0. ]
[0. 0. 0. ]
[0. 0. 0. ]
[0. 0. 0. ]]
[[0. 0. 0.3125]
[0.125 0.25 0.5625]
[0.125 0.1875 0.5 ]
[0.1875 0.3125 0.5625]
[0.1875 0.25 0.5 ]]]]
對於 3d 數組,有多種方法可以進行矩陣乘積:
In [365]: Z.shape
Out[365]: (5, 5, 3)
您說np.dot
無效,但不說明原因:
In [366]: np.dot(Z,Z).shape
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Input In [366], in <cell line: 1>()
----> 1 np.dot(Z,Z).shape
File <__array_function__ internals>:5, in dot(*args, **kwargs)
ValueError: shapes (5,5,3) and (5,5,3) not aligned: 3 (dim 2) != 5 (dim 1)
如果您花時間閱讀np.dot
文檔,您會發現它試圖在 A 的最后一個軸和 B 的最后一個軸上進行乘積之和,因此 3 和 5 之間的不匹配。
你會得到同樣的錯誤是Z
是 (5,3) 形狀。
解決此問題的一種方法是將第二個Z
更改為 (5,3,5) 形狀:
In [367]: np.dot(Z,Z.transpose(0,2,1)).shape
Out[367]: (5, 5, 5, 5)
但是dot
在領先的維度上做了一種外積。
我認為另一個tensordot
中的張量點也可以做到這一點。 tensordot
只是將計算簡化為一個dot
調用,並進行了一些整形和轉置。
matmul/@
將前導維度視為“批處理”並應用正常的broadcasting
規則:
In [368]: np.matmul(Z,Z.transpose(0,2,1)).shape
Out[368]: (5, 5, 5)
使用einsum
,我們可以指定其他軸組合。
In [369]: np.einsum('ijk,ijk->ij',Z,Z).shape
Out[369]: (5, 5)
In [370]: np.einsum('ijk,ijk->ik',Z,Z).shape
Out[370]: (5, 3)
In [371]: np.einsum('ijk,ilk->ijl',Z,Z).shape
Out[371]: (5, 5, 5)
In [373]: np.einsum('ijk,ijl->ijl',Z,Z).shape
Out[373]: (5, 5, 3)
In [374]: np.einsum('ijk,jlk->ilk',Z,Z).shape
Out[374]: (5, 5, 3)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.