运行 构建特征时内存不足(将图像转换为派生特征 [numpy 数组])?

Running out of memory when building features (converting images into derived features [numpy arrays])?

我将一些图像数据复制到 Google 云上的一个实例(8 个 vCPU,64GB 内存,Tesla K80 GPU)并且 运行 在将原始数据转换为特征时遇到内存问题,并改变输出的数据结构。最终我想在 Keras/Tensorflow 神经网络中使用派生特征。

进程

将数据复制到存储桶后,我 运行 一个 build_features.py 函数将原始数据转换为神经网络的处理数据。在此管道中,我首先获取每个原始图像并将其放入列表 x(其中存储派生的特征)。

由于我要处理大量图像(数万张类型为 float32 且尺寸为 250x500x3 的图像),列表 x 变得非常大。 x 的每个元素都是 numpy 数组,以 250x500x3 的形状存储图像。

问题 1 - 随着列表 x 的增长减少内存

我截取了 2 个屏幕截图,显示可用内存随着 x 的增长而减少(下图)。我最终能够完成这一步,但我只剩下几 GB 的内存,所以我绝对想解决这个问题(将来我想处理更大的数据集)。 如何以不受 x 大小限制的方式构建特征?

问题 2 - 将 x 转换为 numpy 数组时出现内存错误

实例实际失败的步骤如下:

x = np.array(x)

失败信息是:

Traceback (most recent call last):
  File "build_features.py", line 149, in <module>
    build_features(pipeline='9_11_2017_fan_3_lights')
  File "build_features.py", line 122, in build_features
    x = np.array(x)
MemoryError

如何调整此步骤以免 运行 内存不足?

您的代码有每个图像的两份副本 - 一份在列表中,一份在数组中:

images = []
for i in range(many):
    images[i] = load_img(i) # here's the first image

x = np.array(images) # joint them all together into a second copy

只需将图像直接加载到数组中

x = np.zeros((many, 250, 500, 3)
for i in range(many):
    x[i] = load_img(i)

这意味着您一次只能持有一张图片的副本。


如果您事先不知道图像的大小或数据类型,或者不想对其进行硬编码,您可以使用:

x0 = load_img(0)
x = np.zeros((many,) + x0.shape, x0.dtype)
for i in range(1, many):
    x[i] = load_img(i)

话虽如此,您在这里走的是一条棘手的道路。如果你没有足够的空间在内存中存储你的数据集两次,你也没有空间来计算 y = x + 1.

您可能要考虑使用 np.float16 以牺牲精度为代价购买更多存储空间