此Python内存优化如何起作用



OpenAI已发布了一组机器学习/强化学习环境,称为'Open AI Gym'。某些环境是基于图像的,因此,与存储100万或数百万帧的环境观测值一起使用算法时,可能会具有很大的内存足迹。

在引用深Q学习的参考实施时,我发现了一对 LazyFrameStackLazyFrames,声称"确保观察值之间只存储了一次的常见框架...以优化内存使用情况,这可能是巨大的。DQN的1M帧重播缓冲区。">

在参考实现中,DEEPQ代理将框架堆叠在一起,然后将其放入重播缓冲区中。查看了这两个类的实现后,对我来说并不明显地保存内存 - 如果有的话,因为LazyFrames基本上是一个四个numpy数组的容器对象,LazyFrame是否应该拥有更大的内存足迹?<<

在python中,对象作为参考传递。这意味着即使懒框对象可能是极大的numpy数组的列表,但该懒框对象本身的大小很小,因为它仅存储对np.ndarray s的引用。换句话说,您可以想到指向np.ndarray数据的LazyFrame,而实际上并不是将单个数组的每个副本存储在自身中。

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

最新更新