Auto Byte

专注未来出行及智能汽车科技

微信扫一扫获取更多资讯

Science AI

关注人工智能与其他前沿技术、基础学科的交叉研究与融合发展

微信扫一扫获取更多资讯

泽南机器之心编译

一番实验后,有关Batch Size的玄学被打破了

有关 batch size 的设置范围,其实不必那么拘谨。

我们知道,batch size 决定了深度学习训练过程中,完成每个 epoch 所需的时间和每次迭代(iteration)之间梯度的平滑程度。batch size 越大,训练速度则越快,内存占用更大,但收敛变慢。

又有一些理论说,GPU 对 2 的幂次的 batch 可以发挥更好性能,因此设置成 16、32、64、128 … 时,往往要比设置为其他倍数时表现更优。

后者是否是一种玄学?似乎很少有人验证过。最近,威斯康星大学麦迪逊分校助理教授,著名机器学习博主 Sebastian Raschka 对此进行了一番认真的讨论

图片

Sebastian Raschka

关于神经网络训练,我认为我们都犯了这样的错误:我们选择批量大小为 2 的幂,即 64、128、256、512、1024 等等。(这里,batch size 是指当我们通过基于随机梯度下降的优化算法训练具有反向传播的神经网络时,每个 minibatch 中的训练示例数。)

据称,我们这样做是出于习惯,因为这是一个标准惯例。这是因为我们曾经被告知,将批量大小选择为 2 的幂有助于从计算角度提高训练效率。

这有一些有效的理论依据,但它在实践中是如何实现的呢?在过去的几天里,我们对此进行了一些讨论,在这里我想写下一些要点,以便将来参考。我希望你也会发现这很有帮助!

理论背景

在看实际基准测试结果之前,让我们简要回顾一下将批大小选择为 2 的幂的主要思想。以下两个小节将简要强调两个主要论点:内存对齐和浮点效率

内存对齐

选择批大小为 2 的幂的主要论据之一是 CPU 和 GPU 内存架构是以 2 的幂进行组织的。或者更准确地说,存在内存页的概念,它本质上是一个连续的内存块。如果你使用的是 macOS 或 Linux,就可以通过在终端中执行 getconf PAGESIZE 来检查页面大小,它应该会返回一个 2 的幂的数字。

图片

这个想法是将一个或多个批次整齐地放在一个页面上,以帮助 GPU 并行处理。或者换句话说,我们选择批大小为 2 以获得更好的内存对齐。这与在视频游戏开发和图形设计中使用 OpenGL 和 DirectX 时选择二次幂纹理类似。

矩阵乘法和 Tensor Core

再详细一点,英伟达有一个矩阵乘法背景用户指南,解释了矩阵尺寸和图形处理单元 GPU 计算效率之间的关系。因此,本文建议不要将矩阵维度选择为 2 的幂,而是将矩阵维度选择为 8 的倍数,以便在具有 Tensor Core 的 GPU 上进行混合精度训练。不过,当然这两者之间存在重叠:

图片

为什么会是 8 的倍数?这与矩阵乘法有关。假设我们在矩阵 A 和 B 之间有以下矩阵乘法:

图片

将两个矩阵 A 和 B 相乘的一种方法,是计算矩阵 A 的行向量和矩阵 B 的列向量之间的点积。如下所示,这些是 k 元素向量对的点积:

图片

每个点积由一个「加」和一个「乘」操作组成,我们有 M×N 个这样的点积。因此,共有 2×M×N×K 次浮点运算(FLOPS)。不过需要知道的是:现在矩阵在 GPU 上的乘法并不完全如此,GPU 上的矩阵乘法涉及平铺。

如果我们使用带有 Tensor Cores 的 GPU,例如英伟达 V100,当矩阵维度 (M、N 和 K)与 16 字节的倍数对齐(根据 Nvidia 的本指南)后,在 FP16 混合精度训练的情况下,8 的倍数对于效率来说是最佳的。

通常,维度 K 和 N 由神经网络架构决定(尽管如果我们自己设计还会有一些回旋余地),但批大小(此处为 M)通常是我们可以完全控制的。

因此,假设批大小为 8 的倍数在理论上对于具有 Tensor Core 和 FP16 混合精度训练的 GPU 来说是最有效的,让我们研究一下在实践中可见的差异有多大。

简单的 Benchmark

为了解不同的批大小如何影响实践中的训练,我运行了一个简单的基准测试,在 CIFAR-10 上训练 MobileNetV3 模型 10 个 epoch—— 图像大小调整为 224×224 以达到适当的 GPU 利用率。在这里,我使用 16 位原生自动混合精度训练在英伟达 V100 卡上运行训练,它更有效地使用了 GPU 的张量核心。

如果想自己运行它,代码可在此 GitHub 存储库中找到:https://github.com/rasbt/b3-basic-batchsize-benchmark

小 Batch Size 基准

我们从批大小为 128 的小基准开始。「训练时间」对应于在 CIFAR-10 上训练 MobileNetV3 的 10 个 epoch。推理时间意味着在测试集中的 10k 图像上评估模型。

图片

查看上表,让我们将批大小 128 作为参考点。似乎将批量大小减少一 (127) 或将批量大小增加一 (129) 确实会导致训练性能减慢。但这里的差异看来很小,我认为可以忽略不计。

将批大小减少 28 (100) 会导致性能明显下降。这可能是因为模型现在需要处理比以前更多的批次(50,000 / 100 = 500 对比 50,000 / 100 = 390)。可能出于类似的原因,当我们将批大小增加 28 (156) 时就可以观察到更快的训练时间。

最大 Batch Size 基准

鉴于 MobileNetV3 架构和输入图像大小,上一节中的批尺寸相对较小,因此 GPU 利用率约为 70%。为了研究 GPU 满负荷时的训练时间差异,我将批量大小增加到 512,以使 GPU 显示出接近 100% 的计算利用率:

图片

由于 GPU 内存限制,批大小不可能超过 515。

同样,正如我们之前看到的,作为 2 的幂(或 8 的倍数)的批大小确实会产生很小但几乎不明显的差异。

多 GPU 训练

之前的基准测试评估了单块 GPU 上的训练性能。不过如今在多 GPU 上训练深度神经网络更为常见。所以让我们看看下面的多 GPU 训练的数字比较:

图片


请注意,推理速度被省略了,因为在实践中我们通常仍会使用单个 GPU 进行推理。此外,由于 GPU 的内存限制,我无法运行批处理大小为 512 的基准测试,因此在这里降低到 256。

正如我们所看到的,这一次 2 的幂和 8 的倍数批量大小 (256) 并不比 257 快。在这里,我使用 DistributedDataParallel (DDP) 作为默认的多 GPU 训练策略。你也可以使用不同的多 GPU 训练策略重复实验。GitHub 上的代码支持 —strategy ddp_sharded (fairscale)、ddp_spawn、deepspeed 等。

基准测试注意事项

这里需要强调的是上述所有基准测试都有注意事项。例如我只运行每个配置一次。理想情况下,我们希望多次重复这些运行并报告平均值和标准偏差。(但这可能不会影响我们的结论,即性能没有实质性差异)

此外,虽然我在同一台机器上运行了所有基准测试,但我以连续的顺序运行它们,运行之间没有很长的等待时间。因此这可能意味着基本 GPU 温度在运行之间可能有所不同,并且可能会对计时产生轻微影响。

我运行基准测试来模仿真实世界的用例,即在 PyTorch 中训练具有相对常见设置的现成架构。然而,正如 Piotr Bialecki 正确指出的那样,通过设置 torch.backends.cudnn.benchmark = True 可以稍微提高训练速度。

其他资源和讨论

正如 Ross Wightman 所提到的,他也不认为选择批量大小作为 2 的幂会产生明显的差异。但选择 8 的倍数对于某些矩阵维度可能很重要。此外 Wightman 指出,在使用 TPU 时批量大小至关重要。(不幸的是,我无法轻松访问 TPU,也没有任何基准比较)

如果你对其他 GPU 基准测试感兴趣,请在此处查看 Thomas Bierhance 的优秀文章:https://wandb.ai/datenzauberai/Batch-Size-Testing/reports/Do-Batch-Sizes-Actually-Need-to-be-Powers-of-2---VmlldzoyMDkwNDQx

特别是你想要比较:

  • 显卡是否有 Tensor Core;
  • 显卡是否支持混合精度训练;
  • 在像 DeiT 这样的无卷积视觉转换器。

Rémi Coulom-Kayufu 的一个有趣的实验表明,2 次方的批大小实际上很糟糕。看来对于卷积神经网络,可以通过以下方式计算出较好的批大小:

Batch Size=int ((n×(1<<14)×SM)/(H×W×C))。

其中,n 是整数,SM 是 GPU 内核的数量(例如,V100 为 80,RTX 2080 Ti 为 68)。

结论

根据本文中共享的基准测试结果,我不认为选择批大小作为 2 的幂或 8 的倍数在实践中会产生明显的差异

然而,在任何给定的项目中,无论是研究基准还是机器学习的实际应用上,都已经有很多旋钮需要调整。因此,将批大小选择为 2 的幂(即 64、128、256、512、1024 等)有助于使事情变得更加简单和易于管理。此外,如果你对发表学术研究论文感兴趣,将批大小选择为 2 的幂将使结果看起来不像是刻意挑选好结果。

虽然坚持批大小为 2 的幂有助于限制超参数搜索空间,但重要的是要强调批大小仍然是一个超参数。一些人认为较小的批尺寸有助于泛化性能,而另一些人则建议尽可能增加批大小。

个人而言,我发现最佳批大小在很大程度上取决于神经网络架构和损失函数。例如,在最近一个使用相同 ResNet 架构的研究项目中,我发现最佳批大小可以在 16 到 256 之间,具体取决于损失函数

因此,我建议始终考虑调整批大小作为超参数优化搜索的一部分。但是,如果因为内存限制而不能使用 512 的批大小,则不必降到 256。有限考虑 500 的批大小是完全可行的。

原文链接:https://sebastianraschka.com/blog/2022/batch-size-2.html
ps://www.theverge.com/2022/7/8/23200961/elon-musk-files-back-out-twitter-deal-breach-of-contract
理论Batch Size
相关数据
深度学习技术

深度学习(deep learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。 深度学习是机器学习中一种基于对数据进行表征学习的算法,至今已有数种深度学习框架,如卷积神经网络和深度置信网络和递归神经网络等已被应用在计算机视觉、语音识别、自然语言处理、音频识别与生物信息学等领域并获取了极好的效果。

机器学习技术

机器学习是人工智能的一个分支,是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、计算复杂性理论等多门学科。机器学习理论主要是设计和分析一些让计算机可以自动“学习”的算法。因为学习算法中涉及了大量的统计学理论,机器学习与推断统计学联系尤为密切,也被称为统计学习理论。算法设计方面,机器学习理论关注可以实现的,行之有效的学习算法。

超参数优化技术

基准技术

一种简单的模型或启发法,用作比较模型效果时的参考点。基准有助于模型开发者针对特定问题量化最低预期效果。

收敛技术

在数学,计算机科学和逻辑学中,收敛指的是不同的变换序列在有限的时间内达到一个结论(变换终止),并且得出的结论是独立于达到它的路径(他们是融合的)。 通俗来说,收敛通常是指在训练期间达到的一种状态,即经过一定次数的迭代之后,训练损失和验证损失在每次迭代中的变化都非常小或根本没有变化。也就是说,如果采用当前数据进行额外的训练将无法改进模型,模型即达到收敛状态。在深度学习中,损失值有时会在最终下降之前的多次迭代中保持不变或几乎保持不变,暂时形成收敛的假象。

损失函数技术

在数学优化,统计学,计量经济学,决策理论,机器学习和计算神经科学等领域,损失函数或成本函数是将一或多个变量的一个事件或值映射为可以直观地表示某种与之相关“成本”的实数的函数。

超参数技术

在机器学习中,超参数是在学习过程开始之前设置其值的参数。 相反,其他参数的值是通过训练得出的。 不同的模型训练算法需要不同的超参数,一些简单的算法(如普通最小二乘回归)不需要。 给定这些超参数,训练算法从数据中学习参数。相同种类的机器学习模型可能需要不同的超参数来适应不同的数据模式,并且必须对其进行调整以便模型能够最优地解决机器学习问题。 在实际应用中一般需要对超参数进行优化,以找到一个超参数元组(tuple),由这些超参数元组形成一个最优化模型,该模型可以将在给定的独立数据上预定义的损失函数最小化。

张量技术

张量是一个可用来表示在一些矢量、标量和其他张量之间的线性关系的多线性函数,这些线性关系的基本例子有内积、外积、线性映射以及笛卡儿积。其坐标在 维空间内,有 个分量的一种量,其中每个分量都是坐标的函数,而在坐标变换时,这些分量也依照某些规则作线性变换。称为该张量的秩或阶(与矩阵的秩和阶均无关系)。 在数学里,张量是一种几何实体,或者说广义上的“数量”。张量概念包括标量、矢量和线性算子。张量可以用坐标系统来表达,记作标量的数组,但它是定义为“不依赖于参照系的选择的”。张量在物理和工程学中很重要。例如在扩散张量成像中,表达器官对于水的在各个方向的微分透性的张量可以用来产生大脑的扫描图。工程上最重要的例子可能就是应力张量和应变张量了,它们都是二阶张量,对于一般线性材料他们之间的关系由一个四阶弹性张量来决定。

神经网络技术

(人工)神经网络是一种起源于 20 世纪 50 年代的监督式机器学习模型,那时候研究者构想了「感知器(perceptron)」的想法。这一领域的研究者通常被称为「联结主义者(Connectionist)」,因为这种模型模拟了人脑的功能。神经网络模型通常是通过反向传播算法应用梯度下降训练的。目前神经网络有两大主要类型,它们都是前馈神经网络:卷积神经网络(CNN)和循环神经网络(RNN),其中 RNN 又包含长短期记忆(LSTM)、门控循环单元(GRU)等等。深度学习是一种主要应用于神经网络帮助其取得更好结果的技术。尽管神经网络主要用于监督学习,但也有一些为无监督学习设计的变体,比如自动编码器和生成对抗网络(GAN)。

卷积神经网络技术

卷积神经网路(Convolutional Neural Network, CNN)是一种前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元,对于大型图像处理有出色表现。卷积神经网路由一个或多个卷积层和顶端的全连通层(对应经典的神经网路)组成,同时也包括关联权重和池化层(pooling layer)。这一结构使得卷积神经网路能够利用输入数据的二维结构。与其他深度学习结构相比,卷积神经网路在图像和语音识别方面能够给出更好的结果。这一模型也可以使用反向传播算法进行训练。相比较其他深度、前馈神经网路,卷积神经网路需要考量的参数更少,使之成为一种颇具吸引力的深度学习结构。 卷积网络是一种专门用于处理具有已知的、网格状拓扑的数据的神经网络。例如时间序列数据,它可以被认为是以一定时间间隔采样的一维网格,又如图像数据,其可以被认为是二维像素网格。

随机梯度下降技术

梯度下降(Gradient Descent)是遵循成本函数的梯度来最小化一个函数的过程。这个过程涉及到对成本形式以及其衍生形式的认知,使得我们可以从已知的给定点朝既定方向移动。比如向下朝最小值移动。 在机器学习中,我们可以利用随机梯度下降的方法来最小化训练模型中的误差,即每次迭代时完成一次评估和更新。 这种优化算法的工作原理是模型每看到一个训练实例,就对其作出预测,并重复迭代该过程到一定的次数。这个流程可以用于找出能导致训练数据最小误差的模型的系数。

批次技术

模型训练的一次迭代(即一次梯度更新)中使用的样本集。

深度神经网络技术

深度神经网络(DNN)是深度学习的一种框架,它是一种具备至少一个隐层的神经网络。与浅层神经网络类似,深度神经网络也能够为复杂非线性系统提供建模,但多出的层次为模型提供了更高的抽象层次,因而提高了模型的能力。

推荐文章
暂无评论
暂无评论~