【问题标题】:What is the right way to manage memory in Theano for training sets that cannot fit in RAM?对于无法放入 RAM 的训练集,在 Theano 中管理内存的正确方法是什么?
【发布时间】:2016-03-15 18:19:34
【问题描述】:

TL;DR: 如何在不占用更多内存的情况下向 Theano 函数提供更多数据?

我遇到的问题是,使用 Theano 在 GPU 上训练我的 ML 算法会导致 GPU 最终耗尽内存。我稍微偏离了教程,因为我的数据集太大而无法完全读入内存(这也一定是视频算法的问题,对吧?),所以我没有使用索引输入和更新方案,而是通过 Theano直接运行ndarrays。

让我举一个例子来说明我的意思。在 Theano 的 Logistic Regression 教程中,它说要按照以下方式做一些事情:

train_model = theano.function(
    inputs=[index],
    outputs=cost,
    updates=updates,
    givens={
        x: train_set_x[index * batch_size: (index + 1) * batch_size],
        y: train_set_y[index * batch_size: (index + 1) * batch_size]
    }
)

这需要将test_set_xtest_set_y 加载到内存中,并且本教程使用SharedVariable 来存储完整 数据集。

好吧,我的数据集是巨大的(很多千兆字节),这意味着它不能一次全部加载到内存中,所以我修改了我的数据以直接获取数据,因此:

train_model = theano.function(
    inputs=[input, classes], 
    outputs=cost, 
    updates=updates
)

然后我做了一些看起来有点像这样的事情:

for count, data in enumerate(extractor):
    observations, labels = data
    batch_cost = train_model(observations, labels)
    logger.debug("Generation %d: %f cost", count, batch_cost)

我想我可能从根本上误解了如何正确地将数据传递给 GPU,而不会出现一些讨厌的 python 垃圾收集脏东西。看起来这只是在模型内部占用越来越多的内存,因为在经过(大量)批次训练后,我收到如下错误:

Error when tring to find the memory information on the GPU: initialization error
Error freeing device pointer 0x500c88000 (initialization error). Driver report 0 bytes free and 0 bytes total 
CudaNdarray_uninit: error freeing self->devdata. (self=0x10cbbd170, self->devata=0x500c88000)
Exception MemoryError: 'error freeing device pointer 0x500c88000 (initialization error)' in 'garbage collection' ignored
Fatal Python error: unexpected exception during garbage collection

如何在不占用更多内存的情况下向 Theano 函数提供更多数据?

【问题讨论】:

    标签: python numpy theano theano-cuda


    【解决方案1】:

    如果数据集不适合内存,则想法是取出其中的一部分并在每次需要时加载它

    如果您的数据不适合 gpu 内存,如经典 lasagne 教程中所示,您可以迭代数据集的一部分,称为小批量

    然后,如果您的数据不适合您的 RAM,您需要在每次需要时加载小批量。最好的方法是让一个单独的进程加载下一个小批量(cpu 工作),因为您正在分析当前的一个(gpu 工作)

    您可以通过AlexNet 激励自己:

    【讨论】:

    • 对,问题不是“小批量如何在概念上工作”,而是“小批量如何在 Theano 的代码中工作”。您无法在代码中明确看到它,但 for count, data in enumerate(extractor): 正是这样做的。问题是他们按照我配置的方式,似乎每次调用train_model 都会分配更多的GPU 内存。如何让它回收内存?
    • 检查一下,你的 .theanorc 中有 allow_gc=False 吗?
    • 您是否在提取器中创建共享变量。如果是,请不要,因为您每次只传递一个小批量,或者如果您真的想这样做,请调用 a_shared_varialbe.set_value() 。我能到这里就这么远了。
    猜你喜欢
    • 2019-01-13
    • 2011-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多