2

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

过程

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

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

问题1 - 减少的存储器作为列表X的增长

我带2米的屏幕截图,显示可用的存储器减小为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 

我该如何调整此步骤,以便不会耗尽内存?

回答

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) 

这意味着,您一次只能保存一张图像的副本。


如果你不知道图像的大小或D型时间提前,或不想进行硬编码它,你可以使用:

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购买更多的存储空间,在精密

+0

的成本,但在我的情况下,第一列表x和numpy的数组x具有相同的名称。所以我不覆盖第一个数组,因此不存储2个副本? – megashigger

+1

@megashigger:该列表只能在数组创建后才能销毁,所以在两者都存在时会有重叠期。你是正确的,如果你设法执行那条线,内存使用率会再次下降到原来的水平 – Eric