我正在尝试用Python实现深度Q学习算法的异步版本,这需要不同进程之间的共享神经网络进行异步更新。我知道由于GIL而在Python中共享对象本身非常困难,我发现可以使用https://docs.python.org/2/library/multiprocessing.html#multiprocessing.Array简单地共享其权重。
但问题是这个Array对象是1D并且不支持reshape()
和flatten()
操作,这意味着每次我想将局部权重复制到全局权限时,我必须得到所有权重,重塑它们并将它们转换为此数组。当我想要重新调整权重时,我需要进行相反的转换,这在计算上非常昂贵。我想知道是否有很好的方法可以将一些共享数组(不需要是这个Array对象)直接集成到神经网络的权重中,这样每次调用update()
时它都会直接修改全局权重?
谢谢!
答案 0 :(得分: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.]]