我正在研究机器学习问题,我的管道中的第一步是将原始数据转换为功能。由于我正在使用非常大的数据集,因此我不断遇到内存问题。这些是我遵循的步骤 - 我想知道这种方法是否存在根本错误。对于上下文,我正在使用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)
问题
当存在更高效的存储机制时,我是否通过使用numpy数组完全错误地接近这个?我需要稍后在Keras神经网络上使用数据,因此使用numpy数组已经方便。
我倾向于遇到上述步骤(1)和步骤(3)的问题。对于第1步,我有时无法执行该行,因为我的内存不足。有趣的是,我在我的慢速本地计算机上没有问题(我猜测它正在使用虚拟内存),但我确实在我的Linux Google Compute实例上遇到了64GB内存的问题。 如何解决此问题?
对于步骤(3),我有时会耗尽内存,我想这是因为当执行该行时我需要双倍的内存(x_train,y_train,x_test,y_test,我会想象需要尽可能多的内存作为x和y)。 有没有办法在不增加内存需求的情况下执行此步骤?
答案 0 :(得分:1)
1 - 在keras中,您可以使用python generator
或keras 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和队列,因为它们是一个非常强大的工具。