1

我试图粗略处理我的 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。如果您的网络不适合,“使其适合”的常见启发式方法是减小批量大小,因为大部分内存通常被激活消耗。

但我不确定一些事情:

  1. 批量大小在此计算中的作用是什么?听起来它只影响激活(也就是说,我应该将激活乘以批量大小)。那是对的吗?
  2. 我怎么知道哪些东西位于我的 GPU(12GiB)上,哪些位于我的 CPU 内存(在 TensorFlow 中)?一般来说,几乎所有这些都驻留在 GPU 上?
  3. 我应该在哪里寻找“杂项”?输入数据是这个的主要来源吗?如果是这样,我是计算一批此类数据还是全部?
4

1 回答 1

1
  1. 你得到了一个使用批量样本训练的模型。单个批次由多个输入组成。这些输入使用模型并行处理。因此,如果您的批次包含一定数量的元素,则每个元素都会从 CPU(输入队列所在的位置)传输到 GPU。因此,GPU 使用状态下的模型t(将此模型视为其参数在时间步冻结的模型t)计算输入批次的每个单个元素的前向传递。然后,将网络结果累积在一个向量中,然后计算反向传播步骤。因此,使用当时的模型计算批次的每个元素的梯度(反向传递)t(再次),在向量中累积并平均。使用这个平均值更新模型参数并且模型进入状态t+1

  2. 根据经验,所有本质上是顺序的东西都在 CPU 上(想想输入线程、队列、单个输入值的处理……)。但是,网络应处理的所有内容随后都会从 CPU 传输到 GPU。

  3. 杂项部分有点混乱。我猜作者是在谈论数据扩充以及单个输入可以以无限方式扩充的事实。因此,您必须考虑到,如果您对一批输入应用变换(例如,对整批图像的随机亮度),这些要计算的变换需要从 CPU 传输到 GPU 和增强版本处理前应存储在 GPU 内存中。然而,传输操作也是一样的,你只是浪费了一些计算时间(当然是为了预处理),分配的内存是一样的

于 2017-06-10T13:33:24.737 回答