梯度累积和batch size有什么关系?

人工智能 比较 梯度下降 随机梯度下降 坡度 批量大小
2021-11-10 01:37:24

我目前正在使用梯度累积训练一些模型,因为模型批次不适合 GPU 内存。由于我使用的是梯度累积,我不得不稍微调整一下训练配置。我调整了两个参数:批量大小和梯度累积步骤。但是,我不确定这个修改的效果,所以我想充分了解梯度累积步骤参数和批量大小之间的关系。

我知道,当您累积梯度时,您只是在更新权重之前为某些步骤添加梯度贡献。通常,每次计算梯度时都会更新权重(传统方法):

wt+1=wtαwtloss

但是在累积梯度时,您会在更新权重之前多次计算梯度(即N梯度累积步骤数):

wt+1=wtα0N1wtloss

我的问题是:批量大小之间有什么关系B和梯度累积步骤N?

例如:以下配置是否等效?

  • B=8,N=1:没有梯度累积(每一步都累积),批量大小为 8,因为它适合内存。
  • B=2,N=4:梯度累积(每 4 步累积),将批量大小减少到 2,因此它适合内存。

我的直觉是他们是,但我不确定。我也不确定是否必须修改学习率α.

1个回答

批量大小和梯度累积步骤之间没有任何明确的关系,除了梯度累积通过巧妙地避免内存问题有助于拟合具有相对较大批量大小的模型(通常在单 GPU 设置中)这一事实。梯度累积的核心思想是使用相同的模型参数执行多次反向传递,然后一次更新多个批次。这与传统方式不同,其中模型参数每更新一次批量大小的样本数。因此,找到正确的批量大小和累积步骤是一个设计权衡,必须基于两件事进行:(i) GPU 可以处理多少批量大小的增加,以及 (ii) 梯度是否累积步骤至少比没有累积的性能要好得多。

至于您的示例配置,理论上是相同的但是,在继续这种直觉之前,有一些重要的警告需要解决。

  1. 使用带有梯度累积的 Batch Normalization 通常效果不佳,仅仅是因为无法累积 BatchNorm 统计信息。更好的解决方案是使用 Group Normalization 而不是 BatchNorm。
  2. 在梯度累积中执行组合更新时,必须确保优化器不会optimizer.zero_grad()在每次反向更新(即 )时初始化为零(即loss.backward())。在训练时很容易将两个语句包含在同一个for循环中,这违背了梯度累积的目的。

这里有一些有趣的资源来了解更多关于它的细节。

  1. Thomas Wolf 关于解决记忆问题的不同方法的文章
  2. Kaggle 关于对学习率影响的讨论:这里这里
  3. PyTorch 中梯度累积的综合答案