Keras 中的 batch_size 对结果质量有影响吗?

数据挖掘 深度学习 喀拉斯
2021-09-24 20:12:03

我即将训练一个包含 2-3 百万篇文章的大型 LSTM 网络,并且正在努力解决内存错误(我使用 AWS EC2 g2x2large)。

我发现一种解决方案是减少batch_size. 但是,我不确定这个参数是否仅与内存效率问题有关,或者它是否会影响我的结果。事实上,我也注意到batch_size在示例中使用的通常是 2 的幂,我也不明白。

我不介意我的网络是否需要更长的时间来训练,但我想知道减少它batch_size是否会降低我的预测质量。

谢谢。

4个回答

一年半后,我回到我的答案,因为我之前的答案是错误的。

批量大小会显着影响学习。当你将一批通过你的网络时会发生什么是你平均梯度。这个概念是,如果你的批大小足够大,这将为完整数据集的梯度提供足够稳定的估计。通过从数据集中抽取样本,您可以估计梯度,同时显着降低计算成本。你走得越低,你的估计就越不准确,但是在某些情况下,这些嘈杂的梯度实际上可以帮助逃避局部最小值。当它太低时,如果您的数据嘈杂并且可能无法学习或收敛速度非常慢,您的网络权重可能会跳来跳去,从而对总计算时间产生负面影响。

批处理的另一个优点是用于 GPU 计算,如果部分计算相同(例如,在网络的相同权重矩阵上重复矩阵乘法),GPU 非常擅长并行化神经网络中发生的计算。这意味着 16 的批大小将少于 8 的批大小的两倍。

如果您确实需要更大的批次大小但它不适合您的 GPU,您可以输入一小批,保存梯度估计并输入一个或多个批次,然后进行权重更新。通过这种方式,您可以获得更稳定的梯度,因为您增加了虚拟批量大小。

我觉得公认的答案可能是错误的。梯度下降算法有变体

  1. Vanilla Gradient Descent:这里的梯度是在单次拍摄的所有数据点上计算的,并取平均值。因此,我们有一个更平滑的梯度版本需要更长的时间来学习。

  2. 随机梯度下降:这里一次只有一个数据点,因此梯度是激进的(噪声梯度),因此会有很多振荡(我们使用动量参数 - 例如 Nesterov 来控制它)。因此,您的振荡有可能使算法无法达到局部最小值。(发散)。

  3. Mini-Batch Gradient Descent:它采用了前面两个的优点,平均小批量的梯度。因此不像 SGD 那样过于激进,并允许 Vanilla GD 不允许的在线学习。

Mini-Batch 越小,模型的性能就越好(并非总是如此),当然这与您的 epoch 学习速度太快有关。如果您在大型数据集上进行训练,您希望更快的收敛和良好的性能,因此我们选择 Batch-GD。

SGD 具有固定的学习参数,因此我们启动了其他自适应优化器,如 Adam、AdaDelta、RMS Prop 等,它们根据梯度的历史改变学习参数。

奇怪的是,我发现使用 keras 的较大批量需要更多的 epoch 才能收敛。

例如,这个脚本基于 keras 的集成测试的输出是

epochs 15   , batch size 16   , layer type Dense: final loss 0.56, seconds 1.46
epochs 15   , batch size 160  , layer type Dense: final loss 1.27, seconds 0.30
epochs 150  , batch size 160  , layer type Dense: final loss 0.55, seconds 1.74

有关的

使用太大的批大小可能会对训练期间网络的准确性产生负面影响,因为它会降低梯度下降的随机性。

编辑:大多数时候,batch_size需要增加来加快计算速度,但还有其他更简单的方法可以做到这一点,比如通过dtype参数使用较小占用空间的数据类型,无论是在keras还是tensorflow中,例如,float32而不是float64

已经发表的几篇论文表明——正如Yann LeCun所说,2020 年的传统观点似乎仍然被说服——大批量对你的健康有害。

两篇相关论文是

这提供了可能的原因。换句话说,大批量可能会陷入局部(“尖锐”)最小值,而小批量则不会。学习率的选择存在一些相互作用。