2016-06-14 38 views
2

我有兩個不同的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] 

的問題是,它的每個I做時間加倍存儲器。不知怎的,舊的數組沒有被刪除,可能是因爲切片操作符創建視圖,我猜。我嘗試了下面的改變,出於純粹的絕望:

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),但答案並沒有幫助我,因爲提供的解決方案需要再次切片。

感謝您的任何幫助。

+1

那些不是意見。您可能在其他地方有其他對原始數組的引用。 – user2357112

+0

*「...因爲切片運算符創建視圖我猜。」*切片*確實*創建視圖,但您顯示的代碼不切片。當你寫'a [perm]'時,就會複製一份。 「切片」是指使用冒號的操作:「開始:結束:步驟」,例如, '0:4','4:'等 –

+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) 
+0

它確實有幫助,謝謝。但是,我確實發現了一個更好的東西:以規避這個問題。我決定不要週期性地洗牌數據,而只是重新創建一個置換矢量並對其進行採樣。我仍然想知道原始解決方案失敗的原因。 – Flonks

+0

然而,這個解決方案需要兩次調用隨機數發生器,這可能會成爲一個性能瓶頸。您可以使用不同的隨機數生成器來減少這種影響。 – Guillaum

+0

@Guillaum是的,對隨機數生成器的兩次調用(以生成相同的序列!)可能是個問題,因此建議進行一些性能測試。如何使用不同的發電機幫助? –

0

其實我不認爲numpy或python有問題。 Numpy使用系統malloc/free分配陣列,這導致內存碎片(請參閱Memory Fragmentation on SO)。

所以我猜你的內存配置文件可能會增加,並在系統能夠減少碎片時突然下降,如果可能的話。

+0

內存以6GB的步長增加,在230GB的時間內,我用64GB的物理內存終止了我的機器上的進程。我不確定這可以完全歸因於碎片。特別是因爲沒有真正的理由,爲什麼應該有超過6GB的內存在較長的時間內使用(除了臨時分配複製等)。 – Flonks