【问题标题】:Memory error regarding operations on numpy arrays关于 numpy 数组操作的内存错误
【发布时间】:2019-10-07 14:21:48
【问题描述】:

我正在实现一个涉及对 numpy 数组进行操作的函数,我得到了 Memory Error 。我明确说明了造成问题的 numpy 数组的维度。

a = np.random.rand(15239,1)
b = np.random.rand(1,329960)
c  = np.subtract(a,b)**2
d = np.random.rand(15239,1)
e = np.random.rand(1,329960)
del a
gc.collect()
f = np.subtract(d,e)**2
del d
gc.collect()
g = np.sqrt(c + f).min(axis=0)
del c,f
gc.collect()

我在运行它们时收到Memory Error

不过,下面给出了使用它们的功能-

def make_weight_map(masks):
    """
    Generate the weight maps as specified in the UNet paper
    for a set of binary masks.

    Parameters
    ----------
    masks: array-like
        A 3D array of shape (n_masks, image_height, image_width),
        where each slice of the matrix along the 0th axis represents one binary mask.

    Returns
    -------
    array-like
        A 2D array of shape (image_height, image_width)

    """
    masks = masks.numpy()
    nrows, ncols = masks.shape[1:]
    masks = (masks > 0).astype(int)
    distMap = np.zeros((nrows * ncols, masks.shape[0]))
    X1, Y1 = np.meshgrid(np.arange(nrows), np.arange(ncols))
    X1, Y1 = np.c_[X1.ravel(), Y1.ravel()].T
    for i, mask in enumerate(masks):
        # find the boundary of each mask,
        # compute the distance of each pixel from this boundary
        bounds = find_boundaries(mask, mode='inner')
        X2, Y2 = np.nonzero(bounds)
        xSum = (X2.reshape(-1, 1) - X1.reshape(1, -1)) ** 2
        ySum = (Y2.reshape(-1, 1) - Y1.reshape(1, -1)) ** 2
        distMap[:, i] = np.sqrt(xSum + ySum).min(axis=0)
    ix = np.arange(distMap.shape[0])
    if distMap.shape[1] == 1:
        d1 = distMap.ravel()
        border_loss_map = w0 * np.exp((-1 * (d1) ** 2) / (2 * (sigma ** 2)))
    else:
        if distMap.shape[1] == 2:
            d1_ix, d2_ix = np.argpartition(distMap, 1, axis=1)[:, :2].T
        else:
            d1_ix, d2_ix = np.argpartition(distMap, 2, axis=1)[:, :2].T
        d1 = distMap[ix, d1_ix]
        d2 = distMap[ix, d2_ix]
        border_loss_map = w0 * np.exp((-1 * (d1 + d2) ** 2) / (2 * (sigma ** 2)))
    xBLoss = np.zeros((nrows, ncols))
    xBLoss[X1, Y1] = border_loss_map
    # class weight map
    loss = np.zeros((nrows, ncols))
    w_1 = 1 - masks.sum() / loss.size
    w_0 = 1 - w_1
    loss[masks.sum(0) == 1] = w_1
    loss[masks.sum(0) == 0] = w_0
    ZZ = xBLoss + loss
    return ZZ

在函数中使用时的错误回溯如下- 我正在使用 32 GB RAM 的系统,我还在 61 GB RAM 上测试了代码-

---------------------------------------------------------------------------
MemoryError                               Traceback (most recent call last)
<ipython-input-32-0f30ef7dc24d> in <module>
----> 1 img = make_weight_map(img)

<ipython-input-31-e75a6281476f> in make_weight_map(masks)
     34         xSum = (X2.reshape(-1, 1) - X1.reshape(1, -1)) ** 2
     35         ySum = (Y2.reshape(-1, 1) - Y1.reshape(1, -1)) ** 2
---> 36         distMap[:, i] = np.sqrt(xSum + ySum).min(axis=0)
     37     ix = np.arange(distMap.shape[0])
     38     if distMap.shape[1] == 1:

MemoryError:

我已经检查了以下问题,但找不到我的问题的解决方案-
Python/Numpy Memory Error
Memory growth with broadcast operations in NumPy

这是Memmap 方法的另一个问题,但我不知道如何在我的用例中应用。

【问题讨论】:

  • c 很大,(15239,329960)。验证这一点。 f 也是如此。 c+f 生成另一个该大小的数组。还有sqrt 另一个。 min 的结果更小,就像b,虽然我不知道它是否必须在内部创建一个临时的大数组。
  • 嗨,是的,c 和 f 的形状为 (15239,329960)c+f 也可以

标签: python numpy bigdata


【解决方案1】:

毫无疑问,这些都是非常大的数组。在 64 位精度下,形状数组 (15239,329960) 需要...

>>> np.product((15239,329960)) * 8 / 2**30
37.46345967054367

...大约 37GiB!尝试的事情:

  • 减少位深度,例如使用np.float16,需要25%的内存。
  • 数据真的密集吗,还是可以用scipy.sparse
  • 也许是时候dask了?
  • 获取更多内存!

【讨论】:

  • 使用`float16时获取Overflow occurred in squared,是的,数据很密集。我想,我现在必须尝试使用​​ dask
  • 你能看看这个问题吗,我在转换为 dask 数组时遇到了。stackoverflow.com/questions/58277168/…
猜你喜欢
  • 2019-07-31
  • 1970-01-01
  • 2017-12-17
  • 2021-10-31
  • 1970-01-01
  • 2016-06-06
  • 1970-01-01
  • 2018-11-22
  • 2015-06-30
相关资源
最近更新 更多