Theano:如何采用"矩阵外部产品"元素是矩阵的地方

时间:2016-01-22 16:35:16

标签: python numpy matrix theano

基本上,我有2个张量:A,其中A.shape = (N, H, D),B,其中B.shape = (K, H, D)。我想做的是得到一个形状为(N, K, D, H)的张量C,使得:

C[i, j, :, :] = A[i, :, :] * B[j, :, :]. 

这可以在Theano中有效地完成吗?

附注:我想要达到的实际最终结果是具有形状(N, K, D)的张量E,使得:

E[i, j, :] = (A[i, :, :]*B[j, :, :]).sum(0)

所以,如果有办法直接得到这个,我更喜欢它(希望节省空间)。

2 个答案:

答案 0 :(得分:2)

可以建议使用broadcasting -

的一种方法
(A[:,None]*B).sum(2)

请注意,在(N, K, H, D)上的总和减少为axis=2之前,正在创建的中间数组的形状为(N,K,D).

答案 1 :(得分:0)

您可以使用batched_dot获取最终的三维结果E,而无需创建大型中间数组:

import theano.tensor as tt
A = tt.tensor3('A')  # A.shape = (D, N, H)
B = tt.tensor3('B')  # B.shape = (D, H, K)
E = tt.batched_dot(A, B)  # E.shape = (D, N, K)

不幸的是,这需要您置换输入和输出数组的尺寸。虽然可以在Theano中使用dimshuffle来完成,但似乎batched_dot无法处理任意跨步数组,因此在评估ValueError: Some matrix has no unit stride时,以下内容会引发E

import theano.tensor as tt
A = tt.tensor3('A')  # A.shape = (N, H, D)
B = tt.tensor3('B')  # B.shape = (K, H, D)
A_perm = A.dimshuffle((2, 0, 1))  # A_perm.shape = (D, N, H)
B_perm = B.dimshuffle((2, 1, 0))  # B_perm.shape = (D, H, K)
E_perm = tt.batched_dot(A_perm, B_perm)  # E_perm.shape = (D, N, K)
E = E_perm.dimshuffle((1, 2, 0))  # E.shape = (N, K, D)

batched_dot在第一个(尺寸D)尺寸上使用scan。当scan顺序执行时,如果在GPU上运行,则计算效率低于并行计算所有产品的效率。

您可以明确地使用batched_dot在广播方法中scan方法的内存效率和并行度之间进行权衡。想法是并行计算大小为C的批次的完整产品M(假设MD的精确因子),使用{{1}批量迭代}}:

scan