【问题标题】:numpy (n, m) and (n, k) to (n, m, k) [duplicate]numpy(n,m)和(n,k)到(n,m,k)[重复]
【发布时间】:2020-01-24 12:57:13
【问题描述】:

x 成为形状为(n, m)np.array

y 成为形状为(n, k)np.array

计算形状(n, m, k)的张量z的正确方法是什么

for all i in [0, n - 1]
z[i] = np.dot(x[i][:, np.newaxis], y[i][np.newaxis, :])

?

换句话说,每一对行(x_i, y_i) 给出一个形状为(m, k) 的矩阵。

我查看了np.tensordot,但经过多次试验,我找不到它的axes 参数的正确值。我不确定它是否适合这项工作。

【问题讨论】:

  • x[:,:, np.newaxis] * y[:, np.newaxis, :] 能完成这项工作吗?由于dot 和轴的大小为1,因此不需要dotmatmul。只需在广播中使用元素明智的乘法。

标签: numpy linear-algebra tensor


【解决方案1】:

你可以像这样使用np.einsum()

z = np.einsum('ij,ik->ijk', x, y)

通过快速测试,这也比基于 np.matmul() 的方法更快(除了非常小的输入):

import numpy as np


x = np.random.randint(1, 100, (2, 3))
y = np.random.randint(1, 100, (2, 4))

%timeit np.einsum('ij,ik->ijk', x, y)
# 100000 loops, best of 3: 3.14 µs per loop
%timeit np.matmul(x[:, :, None], y[:, None, :])
# 100000 loops, best of 3: 2,07 µs per loop


x = np.random.randint(1, 100, (20, 30))
y = np.random.randint(1, 100, (20, 40))

%timeit np.einsum('ij,ik->ijk', x, y)
# 10000 loops, best of 3: 32.1 µs per loop
%timeit np.matmul(x[:, :, None], y[:, None, :])
# 10000 loops, best of 3: 76.8 µs per loop


x = np.random.randint(1, 100, (200, 300))
y = np.random.randint(1, 100, (200, 400))

%timeit np.einsum('ij,ik->ijk', x, y)
# 10 loops, best of 3: 48.7 ms per loop
%timeit np.matmul(x[:, :, None], y[:, None, :])
# 10 loops, best of 3: 68.2 ms per loop

np.dot() 应用于可广播视图,如下所示:

np.dot(x[:, :, None], y[:, None, :])

行不通(它甚至无法达到正确的形状)。

(已编辑)

【讨论】:

  • 谢谢!我总是不愿意使用这个np.einsum 函数,因为它的奇怪字符串参数很难理解。我喜欢将所有内容定义为带有广播的原始 numpy 操作,而不是使用(我发现是)模糊的字符串定义操作。但是谢谢,这增加了讨论
  • @tgy 我还需要一些时间来考虑 np.einsum() 隐式形式的第一个参数或者它是否包含省略号,但我发现这个用例非常简单:它基本上遵循输入和输出形状。此外,它似乎比 np.matmul() 方法更快。
【解决方案2】:

一个简单的np.matmul(x[:, :, None], y[:, None, :]) 就可以了。

来自numpy.matmul的文档:

如果任一参数为 N-D,N > 2,则将其视为驻留在最后两个索引中的矩阵堆栈并相应地广播。

这正是我想做的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-21
    • 1970-01-01
    • 2018-06-18
    • 1970-01-01
    • 1970-01-01
    • 2020-03-28
    • 2023-03-08
    • 1970-01-01
    相关资源
    最近更新 更多