首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >利用np.tensordot实现矩阵的Khatri积

利用np.tensordot实现矩阵的Khatri积
EN

Stack Overflow用户
提问于 2017-04-06 11:19:10
回答 2查看 309关注 0票数 4

我试图把张量(m,n,o)分解成矩阵A(m,r),B (n,r)和C (k,r)。这被称为PARAFAC分解。近身已经完成了这种分解。

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

最近这样做的情况如下:

代码语言:javascript
复制
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_操作。因此,我写了一个更简单的定义如下:

代码语言:javascript
复制
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确实支持np.tensordot

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

预期的解决方案应如下所示:

代码语言:javascript
复制
def tensordot_multplication(A, B, C):
    """
    use np.tensordot
    """
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-04-06 11:27:39

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

我建议两种方法--一种用于broadcasting,另一种用于np.einsum

方法#1 :broadcasting -

代码语言:javascript
复制
(A[:,None,None,:]*B[:,None,:]*C).sum(-1)

说明:

  • A扩展到4D,在axis=(1,2)上引入None/np.newaxis的新轴。
  • 类似地,将B扩展到3D,在axis=(1)中引入新的轴。
  • 保持C的原样,并执行元素乘法,从而生成一个4D数组。
  • 最后,和缩减沿着4D阵列的最后一个轴进行.

按示意图-

代码语言:javascript
复制
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 -

代码语言:javascript
复制
np.einsum('il,jl,kl->ijk',A,B,C)

这里的想法和以前的broadcasting一样,但是字符串符号帮助我们以更简洁的方式传递轴信息。

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

票数 3
EN

Stack Overflow用户

发布于 2017-06-06 00:32:09

您所引用的代码实际上并不是TensorLy如何实现它,而只是文档中给出的一个替代实现。

实际代码中使用的TensorLy是:

代码语言:javascript
复制
def kruskal_to_tensor(factors):
    shape = [factor.shape[0] for factor in factors]
    full_tensor = np.dot(factors[0], khatri_rao(factors[1:]).T)
    return fold(full_tensor, 0, shape)

其中,拉奥是使用numpy.einsum实现的,其方式概括了Divakar的建议。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43253670

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档