Python dask阵列内存错误

Python dask阵列内存错误,python,arrays,out-of-memory,dask,Python,Arrays,Out Of Memory,Dask,我正在实现输入和输出矩阵非常大的神经网络,所以我使用dask数组来存储它们 X是32000 X 7500的输入矩阵,y是相同维度的输出矩阵 下面是具有1个隐藏层的神经网络代码: class Neural_Network(object): def __init__(self,i,j,k): #define hyperparameters self.inputLayerSize = i self.outputLayerSize = j

我正在实现输入和输出矩阵非常大的神经网络,所以我使用dask数组来存储它们

X
是32000 X 7500的输入矩阵,
y
是相同维度的输出矩阵

下面是具有1个隐藏层的神经网络代码:

class Neural_Network(object):
    def __init__(self,i,j,k):
        #define hyperparameters
        self.inputLayerSize = i
        self.outputLayerSize = j
        self.hiddenLayerSize = k
        #weights
        self.W1 = da.random.normal(0.5,0.5,size =(self.inputLayerSize,self.hiddenLayerSize),chunks=(1000,1000))
        self.W2 = da.random.normal(0.5,0.5,size =(self.hiddenLayerSize,self.outputLayerSize),chunks=(1000,1000))
        self.W1 = self.W1.astype('float96')
        self.W2 = self.W2.astype('float96')

    def forward(self,X):
        self.z2 = X.dot(self.W1)
        self.a2 = self.z2.map_blocks(self.sigmoid)
        self.z3 = self.a2.dot(self.W2)
        yhat = self.z3.map_blocks(self.sigmoid)
        return yhat

    def exp(z):
        return np.exp(z)

    def sigmoid(self,z):
        #sigmoid function
##        return 1/(1+np.exp(-z))
        return 1/(1+(-z).map_blocks(self.exp))

    def sigmoidprime(self,z):
        ez = (-z).map_blocks(self.exp)
        return ez/(1+ez**2)

    def costFunction (self,X,y):
        self.yHat = self.forward(X)
        return 1/2*sum((y-self.yHat)**2)

    def costFunctionPrime (self,X,y):
        self.yHat = self.forward(X)
        self.error = -(y - self.yHat)
        self.delta3 = self.error*self.z3.map_blocks(self.sigmoidprime)
        dJdW2 = self.a2.transpose().dot(self.delta3)
        self.delta2 = self.delta3.dot(self.W2.transpose())*self.z2.map_blocks(self.sigmoidprime)
        dJdW1 = X.transpose().dot(self.delta2)
        return dJdW1 , dJdW2
现在,我尝试降低功能成本,如下所示:

>>> n = Neural_Network(7420,7420,5000)
>>> for i in range(0,500):
    cost1,cost2 = n.costFunctionPrime(X,y)
    n.W1 = n.W1 -3*cost1
    n.W2 = n.W2 -3*cost2
    if i%5==0:
        print (i*100/500,'%')
但是当
i
达到120左右时,它会给我错误:

    File "<pyshell#127>", line 3, in <module>
    n.W1 = n.W1 -3*cost1
  File "c:\python34\lib\site-packages\dask\array\core.py", line 1109, in __sub__
    return elemwise(operator.sub, self, other)
  File "c:\python34\lib\site-packages\dask\array\core.py", line 2132, in elemwise
    dtype=dt, name=name)
  File "c:\python34\lib\site-packages\dask\array\core.py", line 1659, in atop
    return Array(merge(dsk, *dsks), out, chunks, dtype=dtype)
  File "c:\python34\lib\site-packages\toolz\functoolz.py", line 219, in __call__
    return self._partial(*args, **kwargs)
  File "c:\python34\lib\site-packages\toolz\curried\exceptions.py", line 20, in merge
    return toolz.merge(*dicts, **kwargs)
  File "c:\python34\lib\site-packages\toolz\dicttoolz.py", line 39, in merge
    rv.update(d)
MemoryError
文件“”,第3行,在
n、 W1=n.W1-3*成本1
文件“c:\python34\lib\site packages\dask\array\core.py”,第1109行,在子文件中__
返回电气设备(operator.sub、self、other)
文件“c:\python34\lib\site packages\dask\array\core.py”,第2132行,在elemwise中
dtype=dt,name=name)
文件“c:\python34\lib\site packages\dask\array\core.py”,第1659行,在顶部
返回数组(合并(dsk,*dsk),输出,块,dtype=dtype)
文件“c:\python34\lib\site packages\toolz\functoolz.py”,第219行,在_调用中__
返回自我。_部分(*args,**kwargs)
文件“c:\python34\lib\site packages\toolz\curried\exceptions.py”,第20行,合并
返回工具Z.merge(*dicts,**kwargs)
文件“c:\python34\lib\site packages\toolz\dicttoolz.py”,第39行,合并
rv.更新(d)
记忆者

当我执行
nn.W1.compute()
时,它也会给出
MemoryError
,这看起来像是在构建图形时失败,而不是在计算期间。我想到两件事:

避免过度循环 for循环的每次迭代都可能会将数百万个任务转储到任务图中。每个任务可能占用大约100B到1kB的空间。当这些加起来,他们可以很容易地压倒你的机器

在深度学习lib库中,像Theano一样,你会使用<代码>扫描>代码>操作。Dask.array没有这样的操作

避免在图中插入图 在一个本身调用map_块的函数上调用map_块

self.delta2 = self.delta3.dot(self.W2.transpose())*self.z2.map_blocks(self.sigmoidprime)

def sigmoidprime(self,z):
    ez = (-z).map_blocks(self.exp)
    return ez/(1+ez**2)
相反,你可以只做一个sigmoid素数函数

def sigmoidprime(z):
    ez = np.exp(-z)
    return ez / (1 + ez ** 2)
然后映射该函数

self.z2.map_blocks(sigmoidprime)
深入学习是很棘手的 一般来说,做好深度学习通常需要专业化。设计来做好这一点的库通常不是通用的,这是有原因的。像dask.array这样的通用库可能很有用,但可能永远无法实现像Theano这样的库的平滑操作

可能的办法
您可以尝试构建一个只需一步的函数。它将从磁盘读取数据,执行所有的点积、转置和常规计算,然后显式存储到磁盘数据集中。然后会多次调用此函数。即使这样,我也不相信dask.array背后的调度策略能很好地完成这一任务。

np.exp()能处理大型dask数组吗?我试着做np.exp(X),其中X是32000x7500,但失败了!现在我该怎么办?它会导致内存错误。。帮助您不应该在dask.array上调用
np.exp
。但是,将它放在由
map\u块调用的函数中是很好的。那么我该怎么做才能避免上述错误呢??请给我建议一条出路。。救命!!我建议您尝试以上所有建议。如果它们因某种原因不起作用,那么提供一个详细但简单的失败例子,并提出一个问题。