2017-02-20 2 views
0

numpyの操作をループ。の簡素化は、私が効率的にpythonで様々なニューラルネットを実装することを学ぶことを試みていると、現在、このモデルに</p> <p><img src="https://i.stack.imgur.com/WIaIy.png" alt="">を実装しようとしています

しかし、私はnumpy演算を使用して合計を実装することに問題があります。

私はthis existing implementationをフォローしていますが、単純化しようとしていますが、実行されているすべての配列操作が達成していることは完全にはわかりません。私の解釈は、CがRの各列に掛けられて合計されるということです。しかし、私のeinsumの実装np.einsum('ijk,km->ij', C, R)は、必要な結果を生成していないようです。

この実装を簡素化するためのいくつかの指摘をお待ちしております。私の現在の試みはnp.einsumを使用することでしたが、それはこれまでのところ私を得ていません。

簡素化するコード(画像/最初のリンクで説明):

小さな wordsを作成
batchsize = X.shape[0] 
R = self.R 
C = self.C 
bw = self.bw 

# Obtain word features 
tmp = R.as_numpy_array()[:,X.flatten()].flatten(order='F') 
tmp = tmp.reshape((batchsize, self.K * self.context)) 
words = np.zeros((batchsize, self.K, self.context)) 
for i in range(batchsize): 
    words[i,:,:] = tmp[i,:].reshape((self.K, self.context), order='F') 
words = gpu.garray(words) 

# Compute the hidden layer (predicted next word representation) 
acts = gpu.zeros((batchsize, self.K)) 
for i in range(self.context): 
    acts = acts + gpu.dot(words[:,:,i], C[i,:,:]) 
+1

あなたが特定の質問/エラーを持っていない限り、これは[コードレビュー]に適しています。 – Julien

+0

@JulienBernu申し訳ありません、ここは新しいです。私は編集しました。 –

+0

「必要な結果」が何であるかを説明する必要もあります。人々はあなたが望むものを理解するために紙全体を掘り起こすことはまずありません。 [mcve]を入力してください。 – Julien

答えて

2

In [565]: words = np.zeros((2,3,4)) 
In [566]: tmp = np.arange(2*3*4).reshape((2,3*4)) 
In [567]: for i in range(2): 
    ...:  words[i,:,:] = tmp[i,:].reshape((3,4),order='F') 
    ...:  
In [568]: tmp 
Out[568]: 
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], 
     [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]]) 
In [569]: words 
Out[569]: 
array([[[ 0., 3., 6., 9.], 
     [ 1., 4., 7., 10.], 
     [ 2., 5., 8., 11.]], 

     [[ 12., 15., 18., 21.], 
     [ 13., 16., 19., 22.], 
     [ 14., 17., 20., 23.]]]) 

私はこれがループ

せずに行うことができますかなり確信しています
In [577]: C = np.ones((4,3,3)) 
In [578]: acts = np.zeros((2,3)) 
In [579]: for i in range(4): 
    ...:  acts += np.dot(words[:,:,i], C[i,:,:]) 
    ...:  
In [580]: acts 
Out[580]: 
array([[ 66., 66., 66.], 
     [ 210., 210., 210.]]) 

このdotループは、einsumで表すことができます。よう:

In [581]: np.einsum('ijk,kjm->im', words, C) 
Out[581]: 
array([[ 66., 66., 66.], 
     [ 210., 210., 210.]]) 

これはjkに合算されます。ループバージョンでは、でjの合計が実行され、kの合計がループ内で実行されました。しかし、非常に大きな配列では、gpuのスピードアップでは、ループバージョンが高速になることがあります。問題のスペースが大きくなりすぎると、einsumは遅くなり、メモリエラーに遭うこともあります(最新バージョンには最適化オプションがいくつかあります)。

wordsは、ループなしtmpから作成することができます。

In [585]: tmp.reshape(2,3,4, order='F') 
Out[585]: 
array([[[ 0, 3, 6, 9], 
     [ 1, 4, 7, 10], 
     [ 2, 5, 8, 11]], 

     [[12, 15, 18, 21], 
     [13, 16, 19, 22], 
     [14, 17, 20, 23]]]) 
関連する問題

 関連する問題