我试图粗略处理我的 TensorFlow 深度学习模型的 GPU 内存占用,并依赖于我发现的启发式建议:
构建 ConvNet 架构时要注意的最大瓶颈是内存瓶颈。许多现代 GPU 的内存限制为 3/4/6GB,最好的 GPU 具有大约 12GB 的内存。有三个主要的内存来源需要跟踪:
来自中间体积大小:这些是 ConvNet 每一层的原始激活数,以及它们的梯度(大小相等)。通常,大多数激活都在 ConvNet 的较早层(即第一个 Conv 层)上。这些被保留是因为它们是反向传播所必需的,但是一个仅在测试时运行 ConvNet 的巧妙实现原则上可以通过仅在任何层存储当前激活并丢弃下面层上的先前激活来大大减少这一点.
从参数大小:这些是保存网络参数的数字,它们在反向传播过程中的梯度,如果优化使用动量、Adagrad 或 RMSProp,通常也是一个步骤缓存。因此,单独存储参数向量的内存通常必须乘以至少 3 倍左右。
每个 ConvNet 实现都必须维护杂项内存,例如图像数据批次,也许是它们的增强版本等。
一旦您粗略估计了值的总数(对于激活、梯度和其他),该数字应转换为以 GB 为单位的大小。取值的个数,乘以 4 得到原始字节数(因为每个浮点数是 4 个字节,或者双精度可能乘以 8),然后多次除以 1024 得到以 KB 为单位的内存量, MB,最后是 GB。如果您的网络不适合,“使其适合”的常见启发式方法是减小批量大小,因为大部分内存通常被激活消耗。
但我不确定一些事情:
- 批量大小在此计算中的作用是什么?听起来它只影响激活(也就是说,我应该将激活乘以批量大小)。那是对的吗?
- 我怎么知道哪些东西位于我的 GPU(12GiB)上,哪些位于我的 CPU 内存(在 TensorFlow 中)?一般来说,几乎所有这些都驻留在 GPU 上?
- 我应该在哪里寻找“杂项”?输入数据是这个的主要来源吗?如果是这样,我是计算一批此类数据还是全部?