我需要帮助来了解神经网络的内存需求以及它们在训练和评估过程之间的差异。更具体地说,是训练过程的内存需求(我使用的是在TensorFlow之上运行的Keras API)。
对于包含N个权重的CNN,使用一批大小为x的权重时,权重本身和输入数据需要恒定的存储量。在前移期间,GPU需要额外的x * N内存单位(具体要求的数量对于问题而言并不重要),以便同时传递所有样本并计算每个神经元的激活。
我的问题是关于反向传播过程的,似乎该过程需要额外的x * N个内存单位(*),以用于每个样本的每个权重的特定梯度。根据我的理解,这意味着该算法将计算每个样本的特定梯度,然后将它们求和以进行反向传播到上一层。
问。由于每批次只有一个更新步骤,为什么不对每个神经元的平均激活进行梯度计算?这样,训练所需的额外内存将仅为(x + 1)* N,而不是2 * x * N。
(*)这是根据我自己的小实验,在评估(〜4200)和训练(〜1200)期间允许的最大批处理量。显然,这是查看内存需求的一种非常简化的方法
答案 0 :(得分:0)
简短的答案是:这就是小型批处理SGD反向传播算法的工作方式。 回顾一下它的起源以及使用标准SGD和小批量SGD之间的区别,为什么会更清楚。
标准随机梯度正则算法将单个样本传递给模型,然后反向传播其梯度并更新模型权重,然后对下一个样本重复此过程。主要缺点是它是一个串行过程(不能同时运行样本,因为每个样本都需要在之前的样本已经更新过的模型上运行),因此计算量非常大。此外,每次更新仅使用一个样本,会导致非常嘈杂的梯度。
小批量SGD 使用相同的原理,但有一个区别-梯度是从多个样本中累积的,更新仅每x个样本执行一次。这有助于在训练过程中获得平滑的渐变,并使多个样本并行通过模型。这是在小批量(通常称为批处理)中使用keras / tensorflow进行训练时使用的算法。
我还没有发现任何有关在每一层中使用梯度平均值进行更新的工作。检查这种算法的结果很有趣。这样做会提高内存效率,但是可能无法达到理想的最低点。