为什么小批量比包含所有训练数据的单个“批量”更好?

数据挖掘 机器学习 深度学习
2021-09-30 20:06:19

我经常读到,在深度学习模型的情况下,通常的做法是在几个训练时期应用小批量(通常是小批量,32/64)。我无法真正理解这背后的原因。

除非我弄错了,否则批量大小是模型在训练迭代期间允许看到的训练实例数;当模型看到每个训练实例时,epoch 是一个完整的回合。如果是这样,我看不到多次迭代训练实例的几乎微不足道的子集的优势,而不是通过在每个回合中将所有可用的训练实例暴露给模型来应用“最大批量”(当然,假设足够记忆)。这种方法的优点是什么?

4个回答

与完整数据集相比,使用小批量的关键优势可以追溯到随机梯度下降1的基本思想。

在批量梯度下降中,您计算​​整个数据集的梯度,对潜在的大量信息进行平均。这样做需要大量内存。但真正的障碍是批量梯度轨迹将你置于一个坏点(鞍点)。

另一方面,在纯 SGD 中,您通过添加(减号)在数据集的单个实例上计算的梯度来更新参数。由于它基于一个随机数据点,因此非常嘈杂,并且可能会在远离批次梯度的方向上偏离。但是,噪声正是您在非凸优化中想要的,因为它可以帮助您摆脱鞍点或局部最小值([2] 中的定理 6)。缺点是效率非常低,您需要多次循环整个数据集才能找到好的解决方案。

minibatch 方法是一种折衷方案,它为每个梯度更新注入足够的噪声,同时实现相对快速的收敛。

1 Bottou, L. (2010)。具有随机梯度下降的大规模机器学习。在 COMPSTAT'2010 会议记录中(第 177-186 页)。物理出版社高清。

[2] Ge, R., Huang, F., Jin, C., & Yuan, Y.(2015 年 6 月)。逃离鞍点——张量分解的在线随机梯度。在 COLT(第 797-842 页)。

编辑 :

我刚刚在 Yann LeCun 的 facebook 上看到了这条评论,这为这个问题提供了一个全新的视角(抱歉不知道如何链接到 fb。)

小批量训练对您的健康不利。更重要的是,这对您的测试错误不利。朋友们不要让朋友们使用大于 32 的 minibatch。让我们面对现实吧:自 2012 年以来,唯一有人改用大于 1 的 minibatch 尺寸是因为 GPU 对于小于 32 的 batch 尺寸效率低下。这是一个可怕的原因。这只是意味着我们的硬件很糟糕。

他引用了前几天(2018年4月)刚发在arXiv上的这篇论文,值得一读,

Dominic Masters, Carlo Luschi, Revisiting Small Batch Training for Deep Neural Networks , arXiv:1804.07612v1

从摘要中,

虽然使用大的小批量增加了可用的计算并行性,但小批量训练已被证明可以提供改进的泛化性能......

对于 m=2 和 m=32 之间的小批量大小,始终获得最佳性能,这与最近提倡使用数千个小批量大小的工作形成鲜明对比。

内存并不是这样做的真正原因,因为您可以在遍历数据集时累积梯度,并在最后应用它们,但在 SGD 中,您仍然在每一步都应用它们。

SGD 被如此广泛使用的原因是:

1)效率。通常,尤其是在训练的早期,不同数据子集的参数梯度往往会指向同一个方向。因此,在 1/100 数据上评估的梯度将大致指向与完整数据集相同的大致方向,但只需要 1/100 的计算。由于在高度非线性的深度网络上的收敛通常需要数千或数百万次迭代,无论您的梯度有多好,因此基于对梯度的廉价估计进行多次更新而不是基于良好估计进行少量更新是有意义的。

2) 优化:嘈杂的更新可能会让你摆脱糟糕的局部最优(尽管我没有资料表明这在实践中很重要)。

3) 泛化。似乎(参见Zhang 等人:Theory of Deep Learning III: Generalization Properties of SGD)SGD 实际上通过在训练集上找到“平坦”最小值来帮助泛化,这更有可能也是测试集上的最小值。直观地说,我们可以将 SGD 视为一种Bagging——通过基于许多小批量数据计算我们的参数,我们加强了在小批量间泛化的规则,并取消了不能泛化的规则,从而使我们不太容易过度拟合训练集。

除非我弄错了,否则批量大小是模型在训练迭代期间允许看到的训练实例数

正确(虽然我称之为“重量更新步骤”)

当模型已经看到每个训练实例时,epoch 是一个完整的回合

正确的

如果是这样,我看不到多次迭代训练实例的几乎微不足道的子集的优势,而不是通过在每个回合中将所有可用的训练实例暴露给模型来应用“最大批量”(当然,假设足够记忆)。这种方法的优点是什么?

嗯,差不多。你通常没有足够的内存。假设我们正在谈论图像分类。ImageNet 是一个广受欢迎的数据集。在很长一段时间内,VGG-16D 是最受欢迎的模型之一。它需要为一张 224x224 图像计算 15 245 800 个浮点数(在特征图中)。这意味着每个图像大约 61MB。这只是在训练每张图像期间需要多少内存的粗略下限。ImageNet 包含数千(我认为大约 120 万?)图像。虽然你可能有那么多主内存,但你肯定没有那么多 GPU 内存。我已经看到 GPU 将速度提高到大约 21 倍。所以你肯定想使用 GPU。

另外:一个小批量的时间要短得多。所以问题是:你宁愿在 GPU 上每小时用小批量更新 n 步,还是在没有 GPU 的情况下用批量更新 m 步,其中 n >> m。

除了其他答案之外,我认为值得指出的是有两个不同但经常耦合的数量:

  1. 用于计算每个步骤中参数梯度的输入数量。

正如其他人所指出的,关于小批量的梯度是真实梯度的近似值。minibatch 越大,近似值越好。

  1. 收集到数组中并“同时”计算的输入数量

这里的权衡纯粹是关于性能(内存/周期)。

这些数量通常是相同的,即小批量大小,但原则上它们可以解耦。