【发布时间】:2020-06-03 01:19:06
【问题描述】:
一些像np.matmul(a, b)这样的numpy函数对矩阵堆栈有方便的行为。
手册指出:
如果任一参数为 N-D,N > 2,则将其视为驻留在最后两个索引中的矩阵堆栈并相应地广播。
因此,对于a.shape = (10 , 2, 4) 和b.shape(10, 4, 2),语句a @ b 是有意义的并且将具有(10, 2, 2) 的形状
但是,我来自线性代数世界,在那里我习惯了 Fortran 连续数组布局。
表示为 Fortran 连续数组的相同 a 将具有形状 (4, 2, 10) 和类似的 b.shape = (2, 4, 10)。
要像以前一样执行a @ b,我必须调用
(a.T @ b.T).T.
更糟糕的是,假设您天真地创建了相同的 Fortran 连续数组 a,并考虑了 matmul 的行为,因此它的形状为 (10, 4, 2)。
然后a.strides = (8, 80, 320) 在“堆栈”索引中具有最小的步幅,实际上应该具有最大的步幅。
这真的是要走的路还是我错过了什么?
【问题讨论】:
-
matmul的第一个维度(共 3 个)是“批量”维度(我认为order不会改变这一点)。所以如果你想玩转置,请使用.transpose(0,2,1)。做一些小数组,看看哪种排列最有意义。 -
二维“C”阶数组的转置是相同数据的“F”阶
view。它只是改变了shape和strides。 -
问题是,为什么这是默认值?为什么要一堆矩阵,其中与“批量维度”对应的步幅最小?
-
当然,我可以使用类似您的
.transpose(0,2,1)解决方案,但这看起来很容易出错,不是吗? -
matmul的 Python 规范根据维度对其进行了定义。order和strides没有被提及。 python.org/dev/peps/pep-0465
标签: numpy numpy-ndarray