python2 - 불필요한 치수 증가없이 텐서를위한 외부 제품을 적용하는 방법?




theano tensor dot example (2)

너는 이런걸 찾고 있니?

>>> a = b = np.arange(8).reshape([2,4])
>>> a[:,None,:]*b[:,:,None]
array([[[ 0,  0,  0,  0],
        [ 0,  1,  2,  3],
        [ 0,  2,  4,  6],
        [ 0,  3,  6,  9]],

       [[16, 20, 24, 28],
        [20, 25, 30, 35],
        [24, 30, 36, 42],
        [28, 35, 42, 49]]])

나는 두 개의 벡터 vw 가지고 있는데, 그 중 m 을 다음과 같이 만들고 싶습니다.

m[i, j] = v[i] * w[j]

다른 말로하면 나는 그것들의 외적 을 계산하려고합니다. 나는 theano.tensor.outer 를 사용하거나 vv 새로운 색인을 추가하고 dot 제품을 사용 theano.tensor.outer 작업을 수행 할 수 있습니다.

m = T.dot(v[:,numpy.newaxis], w[numpy.newaxis,:])

이제 좀 더 일반적인 문제를 해결하려고 노력합니다. 두 벡터 vw 대신 두 개의 행렬 (나는 이것을 vw 라고 부른다)을 가지고 행렬 v 의 각 행의 바깥 쪽 산물을 행렬 w 의 첫 번째 행렬에있는 i 행 두 번째 행렬의 i 번째 행과 곱해집니다). 그래서 나는 그런 것을하고 싶다 :

m1 = T.tensordot(v[:,:, numpy.newaxis], w[:,:,numpy.newaxis], axes = [[2],[2]])
m[i, j, k] = m1[i, k, j, k]

즉, m[:,:,k] 는 행 v k_th 행과 행 wk_th 행의 k_th 에 해당하는 행렬이다.

위의 "솔루션"에 두 가지 문제점이 있습니다. 첫째, 코드의 두 번째 줄은 적절한 theano 코드가 아니기 때문에 실제로는 해결책이 아닙니다. 그래서, 내 첫 번째 질문은 일부 색인을 동일하게 강요하여 "고급 조각"을 수행하는 방법입니다. 예를 들어, m[i, k] = a[i, k, i, i, k] . 둘째로, 나는 두 개의 2D 텐서 (2D tensors)로부터 4D 테스 너 ( m1 )을 먼저 생성 한 다음 다시 3D 텐서로 줄이는 것을 좋아하지 않습니다. 그것은 매우 많은 메모리를 소비 할 수 있습니다. 나는 그것을 피할 수 있다고 생각합니다.


아무도 np.einsum 을 사용하려하지 않았다는 것을 믿을 수 없습니다.

w
array([[1, 8, 9, 2],
       [1, 2, 9, 0],
       [5, 8, 7, 3],
       [2, 9, 8, 2]])

v 
array([[1, 4, 5, 9],
       [9, 1, 3, 7],
       [9, 6, 1, 5],
       [4, 9, 7, 0]])

for i in range(w.shape[0]):
     print(np.outer(w[i], v[i]))

[[ 1  4  5  9]
 [ 8 32 40 72]
 [ 9 36 45 81]
 [ 2  8 10 18]]
[[ 9  1  3  7]
 [18  2  6 14]
 [81  9 27 63]
 [ 0  0  0  0]]
[[45 30  5 25]
 [72 48  8 40]
 [63 42  7 35]
 [27 18  3 15]]
[[ 8 18 14  0]
 [36 81 63  0]
 [32 72 56  0]
 [ 8 18 14  0]]

np.einsum('ij,ik->ijk', w, v)

array([[[ 1,  4,  5,  9],
        [ 8, 32, 40, 72],
        [ 9, 36, 45, 81],
        [ 2,  8, 10, 18]],

       [[ 9,  1,  3,  7],
        [18,  2,  6, 14],
        [81,  9, 27, 63],
        [ 0,  0,  0,  0]],

       [[45, 30,  5, 25],
        [72, 48,  8, 40],
        [63, 42,  7, 35],
        [27, 18,  3, 15]],

       [[ 8, 18, 14,  0],
        [36, 81, 63,  0],
        [32, 72, 56,  0],
        [ 8, 18, 14,  0]]])

동등한 Theano 함수는 theano.tensor.batched_dot ( einsum 보다 훨씬 einsum )이지만 Theano와는 경험이 없습니다.





theano