2

我正在嘗試使用Python的多處理庫來實驗分佈式神經網絡。目前,我已經建立了一個服務器進程創建神經網絡,並將批量輸入到共享隊列中的小批量梯度下降的輸入分塊,由客戶端進程處理,結果放入單獨的共享隊列。使用Python多重處理更新共享只讀數據

到目前爲止,除了爲了處理批次和生成漸變,子進程需要網絡權重的副本,我已經使用多處理數組共享了一個副本。客戶端進程只需要權值的只讀副本,但服務器進程在每個訓練時期後更新本地副本。

我的問題是我如何更新共享內存以反映更改的權重,以便在下一個時代,客戶端進程具有計算梯度的正確值。

+0

您可以將每個批次與網絡權重的狀態配對嗎?即將權重與批次一起排隊。 –

回答

1

我一直在玩multiprocessing自閱讀本文以後發現更新mp.Array中的數據並不難 - 我得到的一點是,使用循環迭代Array時訪問不是原子的。下面的代碼片段設置使用mp.Process一個簡單的主工人組(使用Pool將是更好的,但是這是更快的對我來說),其中一個mp.Array用於其主會經常變化的數據進行同步(儘可能快,因爲它可以)

from multiprocessing import Process, RLock, Array 
from time import sleep 

def worker(n, array, arrayLock): 
    while True: 
     arrayLock.acquire() 
     print("Worker: %i -> %s" % (n, ",".join(str(i) for i in array))) 
     arrayLock.release() 
     sleep(n + 1) 

if __name__ == '__main__': 
    arrayLock = RLock() 
    array = Array('i', range(10), lock=arrayLock) 

    pd = {} 
    for i in range(3): 
     pd[i] = Process(target=worker, args=(i, array, arrayLock)) 
     pd[i].start() 

    try: 
     while True: 
      arrayLock.acquire() 
      for i in range(len(array)): 
       array[i] = -array[i] 
      arrayLock.release() 
    except KeyboardInterrupt: 
     pass 

    for p in pd.values(): 
     p.terminate() 

在下面的輸出

~> python mp_shared.py 
Worker: 0 -> 0,1,2,3,4,5,6,7,8,9 
Worker: 1 -> 0,-1,-2,-3,-4,-5,-6,-7,-8,-9 
Worker: 2 -> 0,1,2,3,4,5,6,7,8,9 
Worker: 0 -> 0,-1,-2,-3,-4,-5,-6,-7,-8,-9 
Worker: 1 -> 0,-1,-2,-3,-4,-5,-6,-7,-8,-9 
Worker: 0 -> 0,1,2,3,4,5,6,7,8,9 

跨進程更新數據所得只是在Array改變值的問題。我打了一個問題,結果是這樣的,雖然(注意數據的交替跡象)

Worker: 0 -> 0,-1,2,-3,4,-5,6,-7,8,-9 
Worker: 1 -> 0,-1,2,-3,4,-5,6,-7,8,-9 
Worker: 2 -> 0,-1,2,-3,4,-5,6,-7,8,-9 

這是由事實爲Array自動創建Lock不會同步整個環路接入引起的當我正在閱讀或寫入陣列時!主進程將壓縮Array中的工作人員鎖定採集之間的變化。

爲了避免這種情況,我只是創建了自己的RLock(需要有一個RLock作爲觸摸Array使得收購,這將阻止如果你已經獲得了Lock),用於與Array使用。我將RLock傳遞給所有工作人員,以便他們每個人都可以進行原子操作(在您的情況下,我確信讀取和寫入操作非常重要,以防止梯度計算出現錯誤)。

編輯:

另一種選擇似乎是mmap,但我不能在它的使用評論,並在改變工作如下期望。

相關問題