【问题标题】:Python MemoryError when not really out of memory?Python MemoryError当不是真的内存不足时?
【发布时间】:2016-06-06 18:51:26
【问题描述】:

我正在尝试对一堆图像 (>40k) 执行平均缩放。当我将大小为 (3,256,256) 的图像读入 np 数组时,内存使用率为 %40(超过 60 GB,使用 htop 检查)。但是,当我运行 arr.std() 时,程序崩溃并给出 MemoryError,即使使用率仍为 %40。

对可能出现的问题有什么想法吗?

【问题讨论】:

  • arr.std() 是否尝试分配一大块内存?如果是这样,并且请求的大小大于剩余内存,则请求将失败并且内存使用量将保持不变...

标签: python image numpy memory


【解决方案1】:

您是否完全确定数组的每个单元只占用 1 个字节,因为默认情况下它可能为单元分配 8 个字节。

我创建了 3 x 3 的小数组,它占用 72 个字节。

import numpy as np a = np.array(np.mat('1, 2, 3; 4, 5, 6; 7, 8, 9')) print(a.nbytes) # Use this .nbytes instead of sys.getsizeof

256 x 256 x 3 x 8 字节 = 1572864 B = 1.5 MB

1.5 MB x 40,000 = 60000 MB \约 58.6 GB

你说你至少有 4 万个,所以如果你有更多,std 正在使用一些内存来展平数组 (请参阅http://docs.scipy.org/doc/numpy-1.9.2/reference/generated/numpy.std.html,你会在这里登陆https://github.com/numpy/numpy/blob/master/numpy/core/_methods.py)你会耗尽内存。

解决方案非常简单:从这里强制字节类型 int8 或其他:http://docs.scipy.org/doc/numpy-1.9.2/user/basics.types.html

a = np.array(np.mat('1, 2, 3, ; 4, 5, 6; 7, 8, 9'), dtype=np.int8) print(a.nbytes) # Only 9 Bytes


检查可用内存尝试pythonic方式(而不是htop):

import psutil m = psutil.virtual_memory() print(m.available)


附:请记住,array.nbytes 显示了仅由数组元素消耗的内存量,没有一些用于数组维护的辅助字节。

【讨论】:

  • 感谢您的回复。我仔细检查了一下,每个单元格占用 1 个字节。我能够加载 20,000 张图像(总图像数组字节 = 5.5GB),并且在使用 arr.std() 时,它占用了总内存的 %93。我想这是我能做到的,但如果能够加载更多内容会很好。
  • @Lamikins 是的,您已经确保每个 图像 中的单元格占用 1B,但是您是否注意到 std 是如何计算的 - 例程 numpy.core._methods._var正在使用 float64 又名 f8 来获取中期结果。只需尝试仅计算一张图像的 std 并在 std 前后使用 psutil 捕获内存使用情况。然后你可以使用更小的 dtype 参数或者为你自己重写 std 。在标准中,他们使用 sqrt(mean(abs(x - x.mean()) ** 2)),但您可以使用来自en.wikipedia.org/wiki/Algorithms_for_calculating_variance 的其他就地算法
  • @Lamikins 您自己的版本应该原位计算方差,然后对其取平方根,但请记住使用数值稳定的算法,例如补偿变量.
猜你喜欢
  • 2013-10-28
  • 1970-01-01
  • 2018-06-23
  • 1970-01-01
  • 2012-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多