Numpy 不使用张量不计算两个张量的点积

Numpy 不使用张量不计算两个张量的点积,numpy,theano,deep-learning,Numpy,Theano,Deep Learning,我想用tensordot来计算两个张量的特定尺寸的点积。比如: A是张量,其形状为(3,4,5) B是张量,其形状为(3,5) 我想用a的第三个暗度和B的第二个暗度做一个点,得到一个暗度为(3,4)的输出 如下图所示: for i in range(3): C[i] = dot(A[i], B[i]) 如何使用tensordot?在这种特定情况下,einsum可能比tensordot更容易理解。例如: c = np.einsum('ijk,ik->ij', a, b) 我将把解

我想用tensordot来计算两个张量的特定尺寸的点积。比如:

A是张量,其形状为(3,4,5) B是张量,其形状为(3,5)

我想用a的第三个暗度和B的第二个暗度做一个点,得到一个暗度为(3,4)的输出

如下图所示:

for i in range(3):
    C[i] = dot(A[i], B[i])

如何使用tensordot?

在这种特定情况下,
einsum
可能比
tensordot
更容易理解。例如:

c = np.einsum('ijk,ik->ij', a, b)
我将把解释简化一点,使事情更容易理解。我们有两个输入数组(用逗号分隔),这将生成输出数组(在
->
的右侧)

  • a
    具有形状
    3,4,5
    ,我们将其称为
    ijk
  • b
    具有形状
    3,5
    ik
  • 我们希望输出
    c
    具有形状
    3,4
    ij
看起来有点不可思议,对吧?让我们把它分解一下

  • 当我们穿过
    ->
    时,我们“丢失”的字母是将被求和的轴。这也是
    dot
    正在做的事情
  • 我们希望输出的形状为
    3,4
    ,因此我们取消了
    k
  • 因此,输出
    c
    应该是
    ij
  • 这意味着我们将把
    b
    称为
    ik
作为一个完整的例子:

import numpy as np

a = np.random.random((3, 4, 5))
b = np.random.random((3, 5))

# Looping through things
c1 = []
for i in range(3):
    c1.append(a[i].dot(b[i]))
c1 = np.array(c1)

# Using einsum instead
c2 = np.einsum('ijk,ik->ij', a, b)

assert np.allclose(c1, c2)

您也可以使用
tensordot
来执行此操作。只要我有更多的时间,我会添加一个例子。(当然,如果其他任何人想同时添加一个
tensordot
示例作为另一个答案,请随意!)

好的,您想在numpy或Theano中使用此选项吗? 在这种情况下,如您所述,您希望将A的轴3与B的轴2收缩,两者都很简单:

import numpy as np

a = np.arange(3 * 4 * 5).reshape(3, 4, 5).astype('float32')
b = np.arange(3 * 5).reshape(3, 5).astype('float32')

result = a.dot(b.T)
在Theano中,这写为

import theano.tensor as T

A = T.ftensor3()
B = T.fmatrix()

out = A.dot(B.T)

out.eval({A: a, B: b})
然而,输出则是形状(3、4、3)。因为您似乎想要一个shape(3,4)的输出,numpy替代方案使用einsum,如下所示

einsum_out = np.einsum('ijk, ik -> ij', a, b)
然而,einsum在Theano中并不存在。因此,这里的具体情况可以模拟如下

out = (a * b[:, np.newaxis]).sum(2)
也可以写在Theano中

out = (A * B.dimshuffle(0, 'x', 1)).sum(2)
out.eval({A: a, B: b})

非常感谢。期待tensordot版本!你似乎想把B的第三个轴乘以A的第二个轴,但你似乎不想保留所有的组合(即形状(3,4,3)和张量的结果)。所以你可能应该指出你想要结果的对角线。