使用Python多处理更新共享只读数据

时间:2013-02-03 01:39:55

标签: python multiprocessing neural-network distributed-computing

我正在尝试使用Python的多处理库来试验分布式神经网络。目前,我进行了设置,以便服务器进程创建神经网络并将输入用于小批量梯度下降,并将批次放入共享队列,由客户端进程处理,并将结果放入单独的共享队列。

到目前为止,一切正常,但为了处理批次并生成渐变,子进程需要一个网络权重的副本,我使用多处理数组共享。客户端进程只需要权重的只读副本,但服务器进程在每个训练时期之后更新本地副本。

我的问题是如何更新共享内存以反映更改的权重,以便在下一个时期,客户端进程具有正确的计算渐变值。

1 个答案:

答案 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

这是由于{I}自动为Lock创建的Array在读取或写入数组时不会同步整个循环的访问而引起的!主进程将在工作人员锁定获取之间进行Array更改。{/ p>

为了避免这种情况,我刚创建了自己的RLock(需要成为RLock,因为触及Array会使其获得,如果您已经获得{{1} }})用于Lock。我将Array传递给所有工作人员,这样他们每个人都可以进行原子操作(在您的情况下,我确信读取和写入是原子的,以防止梯度计算中的错误。)

修改

另一个替代方案似乎是RLock,但我无法评论其使用情况以及更改是否符合要求。