这个Python内存优化如何工作?

问题描述 投票:1回答:1

OpenAI发布了一套名为“Open AI Gym”的机器学习/强化学习环境。一些环境是基于图像的,因此当与存储10万或数百万帧的环境观察的算法一起使用时,可能具有非常大的存储器占用空间。

在深入学习DeepQ Learning的参考实现时,我找到了一对类,LazyFrameStackLazyFrames声称“确保观察之间的公共帧只存储一次......以优化内存使用,这对于DQN的1M帧来说可能是巨大的重播缓冲区。“

在参考实现中,DeepQ代理获取以四个为一组堆叠在一起的帧,然后将这些帧放入重放缓冲区。看过这两个类的实现后,对我来说这些如何节省内存并不明显 - 如果有的话,因为LazyFrames基本上是围绕一组四个numpy数组的容器对象,不应该LazyFrame有更大的内存占用量吗?

python memory
1个回答
2
投票

在Python中,对象作为引用传递。这意味着即使LazyFrame对象可能是一个非常大的numpy数组的列表,LazyFrame对象本身的大小也很小,因为它只存储对np.ndarrays的引用。换句话说,您可以将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(这是一个数组列表)只存储对ab的引用,因此当我们做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
© www.soinside.com 2019 - 2024. All rights reserved.