![](/img/trans.png)
[英]How does this internal Python optimization work for mathematical expressions?
[英]How does this Python memory optimization work?
OpenAI發布了一套名為“ Open AI Gym”的機器學習/強化學習環境。 一些環境是基於圖像的,因此當與存儲10萬或數百萬個幀的環境觀察值的算法一起使用時,可能會占用很大的內存。
在研究DeepQ Learning的參考實現時,我發現了一對類LazyFrameStack
和LazyFrames
,它們聲稱“確保觀察之間的公共幀僅存儲一次...以優化內存使用,這對於DQN的1M幀可能是巨大的重播緩沖區。”
在參考實現中,DeepQ代理將幀以四個為一組的形式堆疊在一起,然后將其放入重播緩沖區中。 看完這兩個類的實現之后,我對它們如何節省內存並不了解-如果有的話,因為LazyFrames
是圍繞四個numpy
數組的容器對象, LazyFrame
不應該占用更大的內存嗎?
在Python中,對象作為參考傳遞。 這意味着,即使LazyFrame對象可能是一個非常大的numpy數組的列表,該LazyFrame對象本身的大小仍然很小,因為它僅存儲對np.ndarray
的引用。 換句話說,您可以想到LazyFrame只是指向np.ndarray
數據,而不是在其內部實際存儲單個數組的每個副本。
import numpy as np
a = np.ones((2,3))
b = np.ones((2,3))
X = [a, b]
print(X)
>>> [array([[1., 1., 1.],
[1., 1., 1.]]),
array([[1., 1., 1.],
[1., 1., 1.]])]
X_stacked = np.stack(X)
print(X_stacked)
>>> array([[[1., 1., 1.],
[1., 1., 1.]],
[[1., 1., 1.],
[1., 1., 1.]]])
a[0] = 2
print(X)
>>> [array([[2., 2., 2.],
[1., 1., 1.]]),
array([[1., 1., 1.],
[1., 1., 1.]])]
print(X_stacked)
>>> array([[[1., 1., 1.],
[1., 1., 1.]],
[[1., 1., 1.],
[1., 1., 1.]]])
如您在這里看到的那樣, X
(這是一個數組列表)僅存儲對a
和b
的引用,因此當我們執行a[0] = 2
,可以通過打印X
看到更改。 但是一旦堆疊了陣列,您實際上就創建了一個具有那么多內存的新陣列。
為了更直接地解決“如何節省內存”的問題,下面是一個示例。
import sys
a = np.random.randn(210, 160, 3)
b = np.random.randn(210, 160, 3)
X = [a,b]
X_stacked = np.stack(X)
print(sys.getsizeof(X))
>>> 80
print(sys.getsizeof(X_stacked))
>>> 1612944
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.