【问题标题】:Recovering memory scipy interpolation恢复内存 scipy 插值
【发布时间】:2014-04-24 21:26:21
【问题描述】:

我正在使用插值模块中的 scipy 的 LinearNDInterpolator,但我在某处丢失了内存。如果有人能告诉我如何恢复它,那就太好了。我正在做类似以下的事情(我在其中跟踪了内存使用情况):

import numpy as np
from scipy import interpolate as irp # mem: 14.7 MB

X = np.random.random_sample( (2**18,2) ) # mem: 18.7 MB
Y = np.random.random_sample( (2**18,1) ) # mem: 20.7 MB
f = irp.LinearNDInterpolator( X, Y ) # mem: 85.9 MB
del f # mem: 57.9 MB

我正在做的插值要小得多,但很多时候会导致最终崩溃。谁能说出这些额外的内存在哪里以及如何恢复它?

编辑 1:

memory_profiler的输出:

Line #    Mem usage    Increment   Line Contents
================================================
4   15.684 MiB    0.000 MiB   @profile
5                             def wrapper():
6   19.684 MiB    4.000 MiB     X = np.random.random_sample( (2**18,2) )
7   21.684 MiB    2.000 MiB     Y = np.random.random_sample( (2**18,1) )
8   86.699 MiB   65.016 MiB     f = irp.LinearNDInterpolator( X, Y )
9   58.703 MiB  -27.996 MiB     del f

编辑 2:

我正在运行的实际代码如下。每个 xtr 是 (2*w^2,w^2) uint8。它一直有效,直到我达到 w=61,但前提是我分别运行每个 w(所以 r_[21] ... r_[51] 并运行每个)。奇怪的是,每个小于 61 的内存仍然占用所有内存,但直到 61 才触底。

from numpy import *
from scipy import interpolate as irp

for w in r_[ 21:72:10 ]:
    print w
    t = linspace(-1,1,w)
    xx,yy = meshgrid(t,t)
    xx,yy = xx.flatten(), yy.flatten()
    P = c_[sign(xx)*abs(xx)**0.65, sign(yy)*abs(yy)**0.65]
    del t

    x = load('../../windows/%d/raw/xtr.npy'%w)
    xo = zeros(x.shape,dtype=uint8)
    for i in range(x.shape[0]):
        f = irp.LinearNDInterpolator( P, x[i,:] )
        out = f( xx, yy )
        xo[i,:] = out
        del f, out

    save('../../windows/%d/lens/xtr.npy'%w,xo)
    del x, xo

它在 61 上出错并显示此消息:

Python(10783) malloc: *** mmap(size=16777216) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
Traceback (most recent call last):
File "make_lens.py", line 16, in <module>
f = irp.LinearNDInterpolator( P, x[i,:] )
File "interpnd.pyx", line 204, in scipy.interpolate.interpnd.LinearNDInterpolator.__init__ (scipy/interpolate/interpnd.c:3794)
File "qhull.pyx", line 1703, in scipy.spatial.qhull.Delaunay.__init__ (scipy/spatial/qhull.c:13267)
File "qhull.pyx", line 1432, in scipy.spatial.qhull._QhullUser.__init__ (scipy/spatial/qhull.c:11989)
File "qhull.pyx", line 1712, in scipy.spatial.qhull.Delaunay._update (scipy/spatial/qhull.c:13470)
File "qhull.pyx", line 526, in scipy.spatial.qhull._Qhull.get_simplex_facet_array (scipy/spatial/qhull.c:5453)
File "qhull.pyx", line 594, in scipy.spatial.qhull._Qhull._get_simplex_facet_array (scipy/spatial/qhull.c:6010)
MemoryError

编辑 3:

与上面相同的代码链接,但与我的数据无关:

http://pastebin.com/BKYzVVTS

我收到与上述相同的错误。我使用的是带有 2GB RAM 的英特尔酷睿 2 双核 macbook。读取 x 和写入 xo 组合仅约 53MB,但随着循环的进行,内存使用量远远超出了所需。

【问题讨论】:

  • 你是如何测量内存消耗的? Python 可能不会释放所有内存,但会将其保存在其内部缓存中以便更快地重新分配。
  • 我在 OSX 上使用活动监视器跟踪上述内容。有没有办法从这个内部缓存中释放内存?我在循环中多次运行上述类似的东西,累积导致崩溃。
  • 啊,那是另一种情况。在这种情况下,Python 不应该积累内存。但是,活动监视器并不是在 Python 中分析内存的好方法。查看这篇文章以获得更好的方法:stackoverflow.com/questions/552744/…
  • 我按照您的链接安装了 memory_profiler,包装和修饰了相关代码,并编辑了上述问题以包含输出。差别不大。
  • 我尝试查看 scipy 源代码,但 LinearNDInterpolator 类隐藏在一些已编译的 python 文件中(我想是出于速度原因)。我对 scipy 源代码的理解不够深入,无法深入挖掘,但似乎 scipy 无法正确处理您的记忆。

标签: python memory memory-management scipy out-of-memory


【解决方案1】:

此问题已在我未使用的更高版本的 SciPy 中得到修复:

https://github.com/scipy/scipy/issues/3471

【讨论】:

    猜你喜欢
    • 2023-04-02
    • 1970-01-01
    • 2016-11-01
    • 1970-01-01
    • 2011-07-04
    • 2013-03-04
    • 2019-06-02
    • 2012-05-31
    • 1970-01-01
    相关资源
    最近更新 更多