切片没有视图(或:改组多个数组)

时间:2016-06-14 19:14:40

标签: python arrays numpy memory-leaks slice

我有两个不同的numpy数组,我想以异步方式对它们进行混洗。

当前解决方案取自https://www.tensorflow.org/versions/r0.8/tutorials/mnist/pros/index.html并按以下步骤进行:

perm = np.arange(self.no_images_train)
np.random.shuffle(perm)
self.images_train = self.images_train[perm]
self.labels_train = self.labels_train[perm]

问题是每次我这样做都会使内存翻倍。不知何故,旧的数组没有被删除,可能是因为切片操作符创建了我猜的视图。出于纯粹的绝望,我尝试了以下改变:

perm = np.arange(self.no_images_train)
np.random.shuffle(perm)

n_images_train = self.images_train[perm]
n_labels_train = self.labels_train[perm]            

del self.images_train
del self.labels_train
gc.collect()

self.images_train = n_images_train
self.labels_train = n_labels_train

仍然相同,内存泄漏,经过几次操作后我的内存不足。

顺便说一句,这两个阵列的等级为100000,224,244,1和100000,1。

我知道这已经在这里处理了(Better way to shuffle two numpy arrays in unison),但答案对我没有帮助,因为提供的解决方案需要再次切片。

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

以同步方式就地置换两个大型数组的一种方法是保存随机数生成器的状态,然后对第一个数组进行洗牌。然后恢复状态并随机播放第二个数组。

例如,这是我的两个数组:

In [48]: a
Out[48]: array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15])

In [49]: b
Out[49]: array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15])

保存随机数生成器的当前内部状态:

In [50]: state = np.random.get_state()

就地a随机播放:

In [51]: np.random.shuffle(a)

恢复随机数生成器的内部状态:

In [52]: np.random.set_state(state)

就地b随机播放:

In [53]: np.random.shuffle(b)

检查排列是否相同:

In [54]: a
Out[54]: array([13, 12, 11, 15, 10,  5,  1,  6, 14,  3,  9,  7,  0,  8,  4,  2])

In [55]: b
Out[55]: array([13, 12, 11, 15, 10,  5,  1,  6, 14,  3,  9,  7,  0,  8,  4,  2])

对于您的代码,这看起来像:

state = np.random.get_state()
np.random.shuffle(self.images_train)
np.random.set_state(state)
np.random.shuffle(self.labels_train)

答案 1 :(得分:0)

实际上我认为numpy或python没有任何问题。 Numpy使用系统malloc / free来分配数组,这会导致内存碎片化(请参阅Memory Fragmentation on SO)。

所以我想如果可能的话,当系统能够减少碎片时,你的内存配置文件可能会增加并突然下降。