将原始图像数据转换为神经网络特征的内存有效方法

时间:2017-09-15 01:50:09

标签: python numpy memory-management google-cloud-platform keras

我正在研究机器学习问题,我的管道中的第一步是将原始数据转换为功能。由于我正在使用非常大的数据集,因此我不断遇到内存问题。这些是我遵循的步骤 - 我想知道这种方法是否存在根本错误。对于上下文,我正在使用64GB RAM的Google Cloud计算机上处​​理10,000个图像。

1 - 创建存储功能的数组

创建numpy数组以存储功能。下面的示例是一个特征数组,它将包含14,000个图像特征,每个特征的高度/宽度为288/512和3个颜色通道。

x = np.zeros((14000, 288, 512, 3)) # 29316

2 - 按顺序读取原始图像,处理它们并将它们放入x

for idx, name in enumerate(raw_data_paths):
    image = functions.read_png(name)
    features = get_feature(image)
    x[idx] = features

3 - 训练/测试分裂

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=test_fraction, random_state=42)

问题

  1. 当存在更高效的存储机制时,我是否通过使用numpy数组完全错误地接近这个?我需要稍后在Keras神经网络上使用数据,因此使用numpy数组已经方便。

  2. 我倾向于遇到上述步骤(1)和步骤(3)的问题。对于第1步,我有时无法执行该行,因为我的内存不足。有趣的是,我在我的慢速本地计算机上没有问题(我猜测它正在使用虚拟内存),但我确实在我的Linux Google Compute实例上遇到了64GB内存的问题。 如何解决此问题?

  3. 对于步骤(3),我有时会耗尽内存,我想这是因为当执行该行时我需要双倍的内存(x_train,y_train,x_test,y_test,我会想象需要尽可能多的内存作为x和y)。 有没有办法在不增加内存需求的情况下执行此步骤?

2 个答案:

答案 0 :(得分:1)

1 - 在keras中,您可以使用python generatorkeras sequence进行训练。然后定义批次的大小。

您将使用fit_generator训练您的模型,传递生成器或序列。将参数max_queue_size调整为最多1(当模型在批处理上工作时,队列将并行加载)

2 - 你真的需要一次使用14000吗?你不能做小批量?

您可以使用np.empty代替np.zeros

3 - 拆分列车和测试数据同样简单:

trainData = originalData[:someSize]    
testData = originalData[somesize:]

使用生成器或序列

这些是您可以按部件加载数据的选项,您可以按照自己的方式定义这些部分。

您确实可以将数据保存在较小的文件中,以便每步加载每个文件。 或者您也可以小批量在发生器内进行整个图像预处理。

有关生成器的简单示例,请参阅此答案:Training a Keras model on multiple feature files that are read in sequentially to save memory

您可以从图像文件列表中创建生成器,将列表分成多个文件,然后在每个步骤中执行预处理:

def loadInBatches(batchSize,dataPaths):

    while True:
        for step in range(0,len(dataPaths),batchSize):

            x = np.empty((batchSize, 288, 512, 3)) 
            y = np.empty(???)

            for idx,name in enumerate(dataPaths[step:step+batchSize])

                image = functions.read_png(name)
                features = get_feature(image)
                x[idx] = features
                y[idx] = ???

            yield (x,y)

答案 1 :(得分:0)

我认为一个好的解决方案,可以解决所有3个问题(或多或少),就是使用Tensorflow。后者提供了创建输入队列的可能性。您可以在Threading and Queues中找到更多信息。这是一种易于使用的扩展训练方式。

由于您以后想要使用神经网络,我建议您有时花费学习TF和队列,因为它们是一个非常强大的工具。