我将一些图像数据复制到 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 大小限制的方式构建功能?
问题 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
购买更多存储空间,但以精度为代价
关于python - 构建特征时内存不足(将图像转换为派生特征 [numpy 数组])?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46211965/