【问题标题】:Python training array too largePython 训练数组太大
【发布时间】:2014-08-22 19:42:51
【问题描述】:

所以我有超过 3000 万个对象需要用作我的训练数据。我的问题很简单:当我通过迭代appending 进程创建我的训练数组时,在某个阈值处,列表变得太大并且 python 被杀死。有什么方法可以解决这个问题?几个小时以来,我一直在努力解决这个问题,但一直在做空!

创建训练数组的代码示例

training_array = []
for ...:
    data = #load data from somewhere
    data_array = [x for x in data] #some large array, 2-3 million objects  
    for item in data_array:
        training_array.append(item.a + item.b)

一段时间后,"killed" 被打印到控制台,python 退出。我怎样才能避免这种情况?

更具体的问题措辞:

我正在尝试在一个非常大的数组上进行训练,但是在制作数组时,python 被杀死了。这个训练算法不能在数据块上训练,但需要一个完整的数组,这限制了我知道如何超越这个问题的唯一方法。是否有另一种方法可以在不使用我所有 RAM 的情况下创建此数组(如果这是实际问题)?

【问题讨论】:

  • 有什么方法可以解决这个问题?。制作更小的数组。
  • 但实际上人们在比我创建的数据集大得多的数据集上进行训练,因此必须有一种方法可以在这种大小的数组上进行训练或在某些方面将其分解,以便 python 可以支持它
  • 这取决于您的硬件以及您使用哪种方法进行训练。解决此问题的一种方法是购买更多 RAM。或者你可以考虑使用某种online trainer。此外,根据型号,您也许可以利用sparse matrices

标签: python arrays


【解决方案1】:
  • data 是 Python 列表吗?如果是,那么

    data_array = [x for x in data]
    

    是不必要的,因为它和说是一样的

    data_array = list(data)
    

    复制data。这使内存量翻倍 需要,但不清楚它的用途。

    另请注意,您可以del data 允许Python 在不再需要时回收data 使用的内存。

  • 另一方面,data 可能是一个迭代器。如果是这样的话, 那么您可以通过避免创建 Python 来节省内存 列表,data_array。特别是,您不需要data_array 定义training_array。你可以替换

    data_array = [x for x in data] #some large array, 2-3 million objects  
    for item in data_array:
        training_array.append(item.a + item.b)
    

    list comprehension

    training_array = [x.a + x.b for x in data]
    
  • 如果您使用 NumPy 并最终希望 training_arary 成为 NumPy 数组,那么您可以通过避免 创建中间 Python 列表,training_array。你 直接从data定义NumPy数组training_data

    training_array = np.fromiter((x.a + x.b for x in data),
                                 dtype=...)
    

    请注意,(x.a + x.b for x in data)generator expression,因此如果我们在此处使用列表推导式,则可以避免所需的大量内存。

    如果您知道data 的长度,请在调用中添加count=... np.fromiter 将加快其性能,因为它允许 NumPy 为最终数组预分配适量的内存。

    您还必须指定正确的数据类型。如果值在 training_array 是浮点数,可以节省内存(以 精度)通过指定具有较小项目大小的 dtype。为了 例如,dtype='float32' 使用 4 将每个浮点数存储在数组中 字节(即 32 位)。通常 NumPy 使用float64,它们是 8 字节浮点数。这样你就可以 通过使用更小的数组创建一个更小的数组(从而节省内存) dtype。

  • 如果您的内存仍然不足,那么您可以使用 np.memmap 创建基于文件的数组而不是基于内存的数组 大批。同样的其他选项包括使用h5pypytables 创建 hdf5 文件。

【讨论】:

    【解决方案2】:

    您可以做一些事情:

    1. 以块的形式处理您的数据 - 这将防止您在任何给定时间拥有一个怪物数组,并且应该有助于降低开销。

    2. 从生成器生成数据 - 生成器是“惰性”评估的,这意味着它们不会同时存在。每个元素都是在您调用它时创建的,而不是更早地创建,这样您就不会拥有一个怪物数组。如果您不熟悉生成器,可能会有点难以弄清楚,但是周围有大量资源。

    针对您的具体问题,试试这个生成器:

    def train_gen(data):
        data_gen = (x for x in data)  #The () here are important as it makes data_gen a generator as well, as opposed to a list
        for item in data_gen:
            yield item.a + item.b
    
    
    data = #load data from somewhere
    training_array = train_gen(data)
    
    for item in training_array:
        #Iterates through training_array, producing one value, then discarding it such that only one item in training_array is in memory at a time
    

    【讨论】:

    • 这些解决方案实际上取决于他想要使用该数组的目的。大多数模型不处理分块数据或观察数据。
    • 我不能使用块,请参阅编辑后的问题。训练模型不支持它。就生成器而言,我需要将生成器转换回列表,这只会给我现在遇到的相同错误(至少我相信)
    猜你喜欢
    • 2021-08-06
    • 2017-07-07
    • 2017-09-21
    • 1970-01-01
    • 2020-05-27
    • 1970-01-01
    • 1970-01-01
    • 2019-01-13
    • 2020-02-10
    相关资源
    最近更新 更多