2

形状(ni * 43 * 91)x67のX行列と、形状67x43x91のWテンソルがあります。niは異なります

Xの最初のni行にWの最初の列を点在させて(ni * 43 * 91)ベクトルyを取得し、yの最初のni要素を取得し、Xの2番目のni行にWの2番目の列を取得する必要があります。 yの2番目のni要素など。Wの列がなくなったら、次の次元に進みます。

私は2つのマスクdim2とdim3を持っており、両方とも(ni * 43 * 91)の形をしています。今これは私がやっていることです(単純化されています)そしてそれは非常に遅いです

for d3 in range(91):
  for d2 in range(43):
    mask = ((dim3 == d3) & (dim2 == d2))
    curr_X = X[mask, :]
    curr_W = W[:,d2,d3]
    curr_y = numpy.dot(curr_X,curr_W)
    y[mask] = curr_y

forループなしでこれを行うことは可能ですか?

4

3 に答える 3

0

私はあなたdim2dim3配列が何であるか、そしてどのようにmask構築されるかを完全には理解していませんが、あなたの説明から、あなたはこれに近い何かが欲しいです:

ni = 10
a, b, c = 43, 91, 67
X = np.random.rand(ni*a*b, c)
W = np.random.rand(c, a, b)

X = X.reshape(ni, a*b, c)
W = W.reshape(c, a*b)

y = np.einsum('ijk, kj -> ij', X, W)
y = y.reshape(-1)

動作するコード、つまりとの完全な説明で質問を更新する場合dim2dim3これを微調整して、まったく同じものが返されるようにすることができます(まだ行われていない場合)。

于 2013-03-22T21:41:43.023 に答える
0

まず、コードが機能しないため、何をしたいのかが明確ではありません。私はあなたがこれをしたいと思うだけです:

from numpy import *
from numpy.random import rand

ni=12
A=67
B=43
C=91


X = rand(ni*B*C,A) 
W = rand(A,B,C)

y = zeros((ni*B*C))

for k in xrange(len(y)):
    b = (k/ni)/C
    c = (k/ni) % C

    #print 'y[%i] = dot(X[%i,:],W[:,%i,%i])'%(k,k,b,c)

    y[k] = dot(X[k,:],W[:,b,c])

A,B,C,ni少し低い値に設定して - 行のコメントをprint外すと、このアルゴリズムが何をするかがすぐにわかります。

それがあなたが望むものなら、このワンライナーでより速く行うことができます:

y2 = sum(X * (W.reshape((A,B*C)).swapaxes(0,1).repeat(ni,axis=0)),axis=1)

いくつかのインデックスの再配置にもかかわらず、ここで重要なトリックは使用するrepeatことです。これは、ループ内でインデックスがステップb,cに対して「フリーズ」し、成長しているからです。nik

現時点では少し急いでいますが、さらに説明が必要な場合は、コメントを残してください.

于 2013-03-26T12:44:56.443 に答える