构建要素时将内存耗尽(将图像转换为派生要素[numpy arrays])?

时间:2017-09-14 06:25:06

标签: python numpy machine-learning tensorflow feature-extraction

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

过程

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

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

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

我拍摄了两张截图,显示可用内存随x增长而减少(下图)。我最终能够完成这一步,但我只留下了几GB的内存,所以我肯定想要解决这个问题(将来我想使用更大的数据集)。 如何以不受x大小限制的方式构建功能?

enter image description here enter image description here

问题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

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

1 个答案:

答案 0 :(得分:2)

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

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以精确度为代价购买更多存储空间