2016-11-04 4 views
2

私はPythonで深いQ-learningアルゴリズムの非同期バージョンを実装しようとしています。これは、非同期更新のために異なるプロセス間で共有されたニューラルネットワークを必要とします。私は、GILのためにPythonでオブジェクト自体を共有することはかなり難しいことを知っています。そして、私は、https://docs.python.org/2/library/multiprocessing.html#multiprocessing.Arrayを使ってその重みを単純に共有することが可能であることを発見しました。異なるPythonプロセス間で異なるニューラルネットワークの共有重みを設定する方法は?

しかし、問題はこのArrayオブジェクトは1Dであり、reshape()flatten()操作をサポートしていないことです。つまり、ローカルウェイトをグローバルウェイトにコピーするたびに、すべてのウェイトを取得し、それらをこの配列に追加します。私がウェイトを元に戻したいときは、逆の変換を行う必要があります。これはかなり計算コストが高くなります。 update()を呼び出すたびに直接グローバル重みを変更するように、共有配列(このArrayオブジェクトである必要はありません)をニューラルネットワークの重みに直接組み込むための良い方法があるのでしょうか?

ありがとうございます!

答えて

1

キーは、何らかの種類の共有メモリ空間を使用してnumpy配列のメモリを割り当てることです。 multiprocessing.Arrayオブジェクトは実際にはこれを達成するための本当に良い方法です。 numpyを使用してArrayオブジェクトのビューを作成すると、すべてのビューがメモリを共有します。メインのプロセスでこれを一度行うこともできますし、作業を開始する前に各子プロセスで一度行うこともできます。私は最初の方法を使って例を書いた。これは決して「プロセス安全」ではないので、独自のロックを使用する必要があることに注意してください。

from multiprocessing import Pool, Array 
import numpy as np 
import ctypes 

shape = (10, 2) 
_shared_array = Array(ctypes.c_double, np.prod(shape), lock=False) 
shared_array = np.frombuffer(_shared_array, dtype='double').reshape(shape) 

def target_func(index, value): 
    shared_array[index, :] = value 

p = Pool(4) 
for i in range(10): 
    p.apply_async(target_func, args=(i, i**2)) 

p.close() 
p.join() 

print shared_array 
# [[ 0. 0.] 
# [ 1. 1.] 
# [ 4. 4.] 
# [ 9. 9.] 
# [ 16. 16.] 
# [ 25. 25.] 
# [ 36. 36.] 
# [ 49. 49.] 
# [ 64. 64.] 
# [ 81. 81.]] 
関連する問題