gpt4 book ai didi

python - 使用 np.tensordot 的矩阵的 Khatri 乘积

转载 作者:太空狗 更新时间:2023-10-30 02:55:12 28 4
gpt4 key购买 nike

我正在尝试将张量 (m, n, o) 分解为矩阵 A(m, r)、B (n, r) 和 C (k, r)。这被称为 PARAFAC 分解。 Tensorly已经做了这种分解。

一个重要的步骤是将 A、B 和 C 相乘以获得形状为 (m, n, o) 的张量。

Tensorly 按如下方式执行此操作:

def kt_to_tensor(A, B, C):
factors = [A, B, C]
for r in range(factors[0].shape[1]):
vecs = np.ix_(*[u[:, r] for u in factors])
if r:
res += reduce(np.multiply, vecs)
else:
res = reduce(np.multiply, vecs)
return res

但是,我使用的包 (Autograd) 不支持 np.ix_ 操作。因此我写了一个更简单的定义如下:

def new_kt_to_tensor(A, B, C):
m, n, o = A.shape[0], B.shape[0], C.shape[0]
out = np.zeros((m, n, o))
k_max = A.shape[1]
for alpha in range(0, m):
for beta in range(0, n):
for delta in range(0, o):
for k in range(0, k_max):
out[alpha, beta, delta]=out[alpha, beta, delta]+ A[alpha, k]*B[beta, k]*C[delta, k]
return out

然而事实证明,这个实现也有一些autograd不支持的方面。但是,autograd 确实支持 np.tensordot

我想知道如何使用 np.tensordot 来获得这个乘法。我认为 Tensorflow 的 tf.tensordot 也会有类似的功能。

预期的解决方案应该是这样的:

def tensordot_multplication(A, B, C):
"""
use np.tensordot
"""

最佳答案

不要认为 np.tensordot 会在这里帮助你,因为它需要展开不参与求和归约的轴,因为我们具有在执行乘法时保持最后一个轴在三个输入之间对齐的对齐要求。因此,使用 tensordot,您将需要额外的处理并需要更多的内存。

我会建议两种方法 - 一种使用 broadcasting另一个是 np.einsum .

方法#1:使用广播 -

(A[:,None,None,:]*B[:,None,:]*C).sum(-1)

解释:

  • A 扩展到 4D,方法是在 axis=(1,2) 处引入新轴,使用 None/np.newaxis .

  • 通过在 axis=(1) 处引入新轴,同样将 B 扩展到 3D

    <
  • 保持 C 不变,并执行逐元素乘法生成 4D 数组。

  • 最后,求和归约沿 4D 数组的最后一个轴进行。

示意性地放置-

A        : m        r
B : n r
C : k r

=> A*B*C : m n k r
=> out : m n k # (sum-reduction along last axis)

方法 #2: 使用 np.einsum -

np.einsum('il,jl,kl->ijk',A,B,C)

此处的想法与之前的广播相同,但字符串符号帮助我们以更简洁的方式传达轴信息。

Broadcasting 当然可以在 tensorflow 上使用,因为它有工具来 expand dimensions ,而 np.einsum 可能不是。

关于python - 使用 np.tensordot 的矩阵的 Khatri 乘积,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43253670/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com