因此,我需要使用超过3000万个对象作为我的训练数据。我的问题很简单:当我通过迭代append
进程创建训练数组时,在某个阈值处,列表变得太大而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"
被打印到consol和python退出。我怎么能避免这个?
我正在尝试训练一个非常大的数组,但在制作数组时,python会被杀死。这种训练算法无法在数据块上进行训练,但需要一个完整的阵列,这限制了我知道如何超越这个问题的唯一方法。有没有另一种方法来创建这个数组而不使用我的所有RAM(如果这是实际问题)?
答案 0 :(得分:3)
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)
training_array = [x.a + x.b for x in data]
如果您正在使用NumPy并且最终希望training_arary
成为
NumPy数组,然后你可以通过避免更多的内存来节省
创建中间Python列表training_array
。您
直接从training_data
定义NumPy数组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为最终阵列预先分配适量的内存。
您还必须指定正确的dtype。如果值在
training_array
是浮点数,你可以节省内存(代价是
精度)通过指定具有较小项目大小的dtype。对于
例如,dtype='float32'
使用4将每个float存储在数组中
字节(即32位)。通常NumPy使用float64
,它是8字节的浮点数。所以你可以
使用较小的数组创建一个较小的数组(从而节省内存)
D型。
答案 1 :(得分:0)
您可以做一些事情:
以块的形式处理您的数据 - 这将使您在任何给定时间都不会拥有怪物数组,并且应该有助于降低开销。
从生成器生成数据 - 生成器被“懒惰地”评估,这意味着它们不会同时存在。每个元素都是在你召唤它时创建的,而不是更快,让你不再拥有怪物阵列。如果你不熟悉它们,发电机可能有点棘手,但是周围有很多资源。
针对您的具体问题,请尝试使用此生成器:
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