dask数组的内存错误

时间:2016-03-29 12:12:49

标签: python arrays out-of-memory dask

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

std::priority_queue是32000 x 7500的输入矩阵,X是相同维度的输出矩阵。

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

y

现在我尝试降低功能成本,如下所示:

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,'%') 达到120左右时,它会给我一个错误:

i

当我执行 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

时,它也会MemoryError

1 个答案:

答案 0 :(得分:0)

这看起来像是在构建图形时失败,而不是在计算过程中。我想到了两件事:

避免过度循环

for循环的每次迭代都可能将数百万个任务转储到任务图中。每项任务可能占用100B到1kB之类的东西。当这些加起来时,它们很容易淹没你的机器。

在像Theano这样的典型深度学习库中,您可以使用scan操作来执行此类操作。 Dask.array没有这样的操作。

避免将图形插入图表

您在自己调用map_blocks的函数上调用map_blocks。

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 prime函数

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

然后映射该功能

self.z2.map_blocks(sigmoidprime)

深度学习很棘手

一般来说,深度学习往往需要专业化。设计得很好的图书馆通常不是一般目的。像dask.array 这样的通用库可能很有用,但可能永远无法实现像Theano这样的库的平滑操作。

一种可能的方法

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